Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,21 @@ AdLint currently has three demo-friendly entry points:
2. **Local Web UI** — paste copy, configure platform/industry/model settings, review findings, and export reports.
3. **FastAPI** — embed `/analyze` into internal tools or CI workflows.

Suggested screenshot/GIF flow for the public repo:
![AdLint Web UI review](docs/assets/adlint-ui-review.png)

The demo intentionally uses risky health/weight-loss copy so the review surface
shows matched evidence, recommended actions, and safer rewrite suggestions.
Risk scores are heuristic decision-support signals, not compliance guarantees.

Example generated reports:

- [`docs/assets/demo/adlint-report.md`](docs/assets/demo/adlint-report.md)
- [`docs/assets/demo/adlint-report.json`](docs/assets/demo/adlint-report.json)

Reproduce the CLI demo:

```bash
adlint scan examples/high_risk_tiktok_health.json --format markdown
adlint scan examples/meta_high_risk_health.json --format markdown --output-dir docs/assets/demo
make api # then open http://127.0.0.1:8000/ui/
```

Expand Down Expand Up @@ -106,7 +117,7 @@ make dev # install and run the high-risk example, writing reports/
make scan # install and run the wellness example
make api # start uvicorn with adlint.api:app
make eval # run the seed evals and write evals/results/latest.json
make benchmark # run the 209-row synthetic policy regression benchmark
make benchmark # run the 213-row synthetic policy regression benchmark
make policy-coverage # refresh docs/policy_coverage_matrix.md
make policy-coverage-validate # check the committed coverage matrix
make rewrite-quality # run the deterministic rewrite-quality rubric eval
Expand Down Expand Up @@ -473,6 +484,8 @@ High-value contribution areas:
## Related docs

- `docs/open_source_goal.md`
- `docs/release_v0.1.0.md`
- `docs/announcement_draft.md`
- `docs/policy_design.md`
- `docs/meta_ads_scope.md`
- `docs/legal_disclaimer.md`
Expand Down
1 change: 1 addition & 0 deletions adlint/static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ <h2>Draft ad</h2>
<option value="google">Google</option>
<option value="tiktok">TikTok</option>
<option value="linkedin">LinkedIn</option>
<option value="meta">Meta</option>
</select>
</label>

Expand Down
71 changes: 71 additions & 0 deletions docs/announcement_draft.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Announcement draft

## Short post

I open-sourced **AdLint** — a local-first linting tool for ads, landing pages,
and growth campaigns before they hit platform review.

Think ESLint, but for risky ad claims:

- Flags unsupported health/finance claims, disclosure gaps, platform-policy review triggers, landing-page mismatch, privacy-sensitive tracking, and brand-safety concerns.
- Runs locally through a CLI, FastAPI service, or small Web UI.
- Uses transparent YAML policy rules and eval gates instead of black-box compliance theater.
- Keeps raw ad copy out of storage by default.
- Includes initial Google, TikTok, LinkedIn, and Meta Ads heuristic modules.

It is not legal advice and it does not guarantee platform approval. The goal is
simple: give growth teams earlier, explainable feedback before campaign review
becomes expensive.

Repo: https://github.com/ftchvs/AdLint

## Longer post

Growth teams usually find ad risk late — during platform review, legal review,
or after a landing page is already collecting traffic.

I wanted a lightweight preflight step that works like developer tooling:
transparent, local, scriptable, and easy to extend.

So I open-sourced **AdLint**.

AdLint scans draft ad copy and optional landing-page context, then returns:

- `approved`, `needs_review`, or `high_risk`
- exact matched evidence
- policy categories and severity
- recommended actions
- safer rewrite options
- JSON/Markdown reports

The project is intentionally local-first. The rule engine is deterministic and
policy-as-code-first. There is also an optional Ollama-compatible local model
reviewer, but the baseline does not depend on hosted models.

What is in the first OSS release:

- CLI, API, and Web UI
- policy YAML files
- initial platform modules for Google, TikTok, LinkedIn, and Meta Ads
- privacy/disclosure/landing-page/brand-safety checks
- seed evals, benchmark evals, real-case fixtures, and policy coverage gates

What it does *not* claim:

- legal advice
- definitive compliance decisions
- guaranteed platform approval
- complete Meta/Google/TikTok/LinkedIn policy parity

If you work on growth, regulated campaigns, creator ads, landing pages, or local
AI/product tooling, I’d love feedback and contributions.

Repo: https://github.com/ftchvs/AdLint

## Product Hunt / Hacker News style blurb

AdLint is a local-first ad preflight tool for growth teams. It scans draft ad
copy and landing-page context for risky claims, disclosure gaps, platform-policy
review triggers, privacy-sensitive tracking, and brand-safety concerns. It ships
with CLI/API/Web UI workflows, transparent YAML policy rules, eval gates, and an
optional local AI reviewer.
Binary file added docs/assets/adlint-ui-review.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
118 changes: 118 additions & 0 deletions docs/assets/demo/adlint-report.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
{
"decision": "high_risk",
"enabled_modules": [
"brand_safety",
"health_claims",
"platform",
"privacy"
],
"landing_page": {
"disclaimers": [],
"fetch_error": null,
"forms": [],
"headings": [],
"pricing_text": [],
"title": null,
"tracking_scripts": [],
"url": null,
"visible_claims": []
},
"logging_enabled": false,
"model": {
"enabled": false,
"provider": null,
"status": "disabled"
},
"policy_hits": [
{
"category": "health_claims",
"description": "Health or wellness claim likely requiring substantiation.",
"evidence": [
{
"source": "body",
"text": "Our clinically proven supplement helps you lose 20 pounds and melts fat."
}
],
"policy_id": "unsupported_health_claim",
"recommended_action": "Remove or qualify the claim and provide substantiation.",
"severity": "high"
},
{
"category": "health_claims",
"description": "Weight-loss and body-image claims can trigger platform and FTC review.",
"evidence": [
{
"source": "body",
"text": "Our clinically proven supplement helps you lose 20 pounds and melts fat."
}
],
"policy_id": "weight_loss_claim",
"recommended_action": "Avoid absolute body or fat-loss language and route for review.",
"severity": "high"
},
{
"category": "health_claims",
"description": "Before-and-after framing can imply atypical guaranteed results.",
"evidence": [
{
"source": "headline",
"text": "Are you overweight? See a before and after transformation"
}
],
"policy_id": "before_after_claim",
"recommended_action": "Add context, substantiation, and typical-results disclosure.",
"severity": "medium"
},
{
"category": "platform_policy",
"description": "Meta ads should not imply knowledge of a viewer's health, body, or medical condition.",
"evidence": [
{
"source": "headline",
"text": "Are you overweight? See a before and after transformation"
}
],
"policy_id": "meta_personal_attributes_health",
"recommended_action": "Reframe the ad around the product or service benefit without implying personal health attributes.",
"severity": "high"
},
{
"category": "platform_policy",
"description": "Meta health and appearance ads can be rejected for unrealistic results or negative self-perception framing.",
"evidence": [
{
"source": "headline",
"text": "Are you overweight? See a before and after transformation"
},
{
"source": "body",
"text": "Our clinically proven supplement helps you lose 20 pounds and melts fat."
}
],
"policy_id": "meta_health_appearance_results",
"recommended_action": "Avoid transformation framing and use qualified wellness-support language.",
"severity": "high"
}
],
"recommended_actions": [
"Remove or qualify the claim and provide substantiation.",
"Avoid absolute body or fat-loss language and route for review.",
"Reframe the ad around the product or service benefit without implying personal health attributes.",
"Avoid transformation framing and use qualified wellness-support language.",
"Add context, substantiation, and typical-results disclosure."
],
"requires_review": true,
"risk_score": 0.9,
"safer_rewrites": [
{
"body": "Our developed with evidence-informed guidance supplement helps you lose 20 pounds and melts fat. Results vary.",
"cta": "Learn more",
"headline": "Are you overweight? See a before and after transformation"
},
{
"body": "Designed to complement healthy habits. Individual results vary.",
"cta": "Learn more",
"headline": "Support your wellness routine with daily nutrition"
}
]
}
76 changes: 76 additions & 0 deletions docs/assets/demo/adlint-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# AdLint Report

- Decision: `high_risk`
- Risk score: `0.90`
- Requires review: `true`
- Model status: `disabled`

## Policy Hits

### unsupported_health_claim

- Severity: `high`
- Category: `health_claims`
- Recommended action: Remove or qualify the claim and provide substantiation.
- Evidence:
- `body`: Our clinically proven supplement helps you lose 20 pounds and melts fat.

### weight_loss_claim

- Severity: `high`
- Category: `health_claims`
- Recommended action: Avoid absolute body or fat-loss language and route for review.
- Evidence:
- `body`: Our clinically proven supplement helps you lose 20 pounds and melts fat.

### before_after_claim

- Severity: `medium`
- Category: `health_claims`
- Recommended action: Add context, substantiation, and typical-results disclosure.
- Evidence:
- `headline`: Are you overweight? See a before and after transformation

### meta_personal_attributes_health

- Severity: `high`
- Category: `platform_policy`
- Recommended action: Reframe the ad around the product or service benefit without implying personal health attributes.
- Evidence:
- `headline`: Are you overweight? See a before and after transformation

### meta_health_appearance_results

- Severity: `high`
- Category: `platform_policy`
- Recommended action: Avoid transformation framing and use qualified wellness-support language.
- Evidence:
- `headline`: Are you overweight? See a before and after transformation
- `body`: Our clinically proven supplement helps you lose 20 pounds and melts fat.

## Recommended Actions

- Remove or qualify the claim and provide substantiation.
- Avoid absolute body or fat-loss language and route for review.
- Reframe the ad around the product or service benefit without implying personal health attributes.
- Avoid transformation framing and use qualified wellness-support language.
- Add context, substantiation, and typical-results disclosure.

## Safer Rewrites

### Option 1

- Headline: Are you overweight? See a before and after transformation
- Body: Our developed with evidence-informed guidance supplement helps you lose 20 pounds and melts fat. Results vary.
- CTA: Learn more

### Option 2

- Headline: Support your wellness routine with daily nutrition
- Body: Designed to complement healthy habits. Individual results vary.
- CTA: Learn more


## Decision-Support Disclaimer

AdLint is a preflight decision-support tool. It does not provide legal advice, guarantee platform approval, or make definitive statutory violation determinations.
62 changes: 62 additions & 0 deletions docs/release_v0.1.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# AdLint v0.1.0 release notes

AdLint is an open-source, local-first preflight tool for ads, landing pages, and
growth campaigns before they hit platform review.

Think **ESLint for risky ad claims**: transparent policy-as-code checks,
evidence-backed findings, safer rewrite suggestions, and eval gates that run
locally.

## What ships in v0.1.0

- **CLI preflight**: scan JSON/YAML campaign configs and export JSON or Markdown reports.
- **Local API + Web UI**: paste ad copy, choose platform/industry/modules, and review findings locally.
- **Policy-as-code**: inspectable YAML rules for health claims, platform policies, privacy, disclosure, landing-page mismatch, and brand safety.
- **Platform modules**: initial Google, TikTok, LinkedIn, and Meta Ads heuristic coverage.
- **Evidence-based output**: every finding includes matched copy, severity, category, and a recommended action.
- **Safer rewrites**: deterministic rewrite suggestions for common high-risk or review-required findings.
- **Local-first posture**: no default raw ad persistence; optional run logging/storage are opt-in.
- **Eval gates**: seed evals, benchmark evals, real-case fixtures, policy coverage validation, and PR preflight checks.
- **Optional local AI reviewer**: Ollama-compatible model review can add decision-support metadata, but deterministic rules remain the trusted baseline.

## Demo

![AdLint Web UI review](assets/adlint-ui-review.png)

The screenshot intentionally uses risky health/weight-loss copy so the review
surface shows policy hits, evidence, and rewrite suggestions. Risk scores are
heuristic decision-support signals, not statistical compliance probabilities.

Example report output is available at:

- `docs/assets/demo/adlint-report.md`
- `docs/assets/demo/adlint-report.json`

## Honest scope

AdLint is decision-support software. It does **not** provide legal advice,
guarantee platform approval, or make definitive statutory determinations.

The Meta Ads module is intentionally framed as **initial heuristic coverage**,
not full Meta policy parity. See `docs/meta_ads_scope.md` for source references,
coverage notes, and non-goals.

## Good first contributions

- Add public-source/paraphrased eval cases.
- Add policy rules with positive and near-miss examples.
- Improve the optional local AI reviewer and measure whether it adds signal or noise.
- Add demo assets, docs, and first-run workflow polish.

## Launch positioning

Suggested announcement line:

> I open-sourced AdLint: a local-first linting tool for ads, landing pages, and
growth campaigns before they hit platform review.

Hooks:

- Runs locally; no ad copy leaves your machine by default.
- Policy-as-code + evals, not black-box compliance theater.
- CLI/API/Web UI for growth teams that want preflight feedback before launch.
4 changes: 4 additions & 0 deletions tests/test_ui_static.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,7 @@ def test_geist_style_system_font_and_restrained_surfaces_are_preserved() -> None
assert "line-height: 0.98;" in STYLES_CSS
assert ".primary-button," in STYLES_CSS
assert "border-radius: 5px;" in STYLES_CSS


def test_platform_select_includes_meta_ads() -> None:
assert '<option value="meta">Meta</option>' in INDEX_HTML
Loading