diff --git a/README.md b/README.md index 5b8b076..ad0ede1 100644 --- a/README.md +++ b/README.md @@ -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/ ``` @@ -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 @@ -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` diff --git a/adlint/static/index.html b/adlint/static/index.html index 1230589..3acae5b 100644 --- a/adlint/static/index.html +++ b/adlint/static/index.html @@ -52,6 +52,7 @@

Draft ad

+ diff --git a/docs/announcement_draft.md b/docs/announcement_draft.md new file mode 100644 index 0000000..d1926dd --- /dev/null +++ b/docs/announcement_draft.md @@ -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. diff --git a/docs/assets/adlint-ui-review.png b/docs/assets/adlint-ui-review.png new file mode 100644 index 0000000..53ba965 Binary files /dev/null and b/docs/assets/adlint-ui-review.png differ diff --git a/docs/assets/demo/adlint-report.json b/docs/assets/demo/adlint-report.json new file mode 100644 index 0000000..7f6e476 --- /dev/null +++ b/docs/assets/demo/adlint-report.json @@ -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" + } + ] +} diff --git a/docs/assets/demo/adlint-report.md b/docs/assets/demo/adlint-report.md new file mode 100644 index 0000000..5957459 --- /dev/null +++ b/docs/assets/demo/adlint-report.md @@ -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. diff --git a/docs/release_v0.1.0.md b/docs/release_v0.1.0.md new file mode 100644 index 0000000..f8af825 --- /dev/null +++ b/docs/release_v0.1.0.md @@ -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. diff --git a/tests/test_ui_static.py b/tests/test_ui_static.py index cad6882..b4d8847 100644 --- a/tests/test_ui_static.py +++ b/tests/test_ui_static.py @@ -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 '' in INDEX_HTML