Skip to main content

warrant-mini

A miniature AI marketing-compliance checker. Give it marketing copy — pasted text, a .txt/.md file, or a URL — and it reviews the copy against a small library of real marketing-compliance rules, returning risk-tiered findings with a reasoning trace and a suggested fix for each.

Inspired by what Warrant does, built as a compact, readable reference implementation.

The CLI (warrant-mini check) on a snippet of planted violations:

warrant-mini CLI output — risk-tiered findings for planted violations

…and the same engine as a web app (warrant-mini serve):

warrant-mini web UI — a reviewed influencer post with risk-tiered findings


60-second quickstart

# 1. install deps (uses uv)
uv sync

# 2. add your Anthropic API key
cp .env.example .env && $EDITOR .env       # or: export ANTHROPIC_API_KEY=sk-ant-...

# 3. review something
uv run warrant-mini check examples/fintech_landing.md      # planted violations
uv run warrant-mini check examples/clean_newsletter.md     # should stay quiet
uv run warrant-mini check examples/influencer_post.txt     # missing #ad disclosure

# other inputs
uv run warrant-mini check "Guaranteed 20% returns, FDIC insured!"   # literal text
uv run warrant-mini check https://example.com/landing-page          # a URL
uv run warrant-mini check examples/fintech_landing.md --json        # machine-readable

# see the rules it checks against
uv run warrant-mini rules

# or use the web UI
uv run warrant-mini serve            # → http://127.0.0.1:8000

Each finding carries a severity tier:

Tier Meaning
P1 Critical — clear legal exposure (e.g. false "FDIC insured", guaranteed returns)
P2 High — e.g. missing required disclosure, undisclosed material connection
P3 Moderate — e.g. unsubstantiated superlative, buried disclaimer
P4 Review suggested — low-confidence / judgment call, flagged for a human

What it checks (the rule library)

Eight real rules, hardcoded in warrant_mini/rules.yaml with citations, grouped for focused review passes:

Group Rules
financial FINRA Rule 2210 (fair & balanced) · Reg DD / Truth in Savings (APY/APR accuracy) · FDIC/NCUA insured-claim accuracy
claims FTC "free" + negative-option billing · superlative substantiation ("best"/"#1"/"guaranteed") · required-disclaimer proximity
disclosure FTC 16 CFR Part 255 (endorsement / material-connection) · sweepstakes / contest disclosure

Editing the rule set is a YAML change — no code.


Architecture

input_loader → checker (per-group LLM judge passes) → verify → rich CLI / JSON
     │              │                                     │
 text/file/URL   claude-opus-4-8, structured outputs   drop fabricated findings
  • input_loader.py — resolves pasted text, a file path, or a URL (fetched and stripped to visible text) into clean plain text.
  • checker.py — runs one LLM judge pass per rule-group, concurrently. Each pass carries only its handful of related rules, which keeps prompts short, improves recall, and isolates a noisy rule from the rest.
  • Structured outputs — the judge is constrained to a Pydantic schema via messages.parse(), so every finding is valid JSON — never scraped from prose.
  • rules.yaml / rules.py — the rule library and its loader/validator.
  • cli.pywarrant-mini check (rich, severity-colored report) and --json, plus warrant-mini rules.

How it avoids hallucinated regulations

Structured output guarantees shape, not truth — so the checker verifies every finding against reality before showing it (see checker.py):

  1. Rule grounding. A finding's rule_id must be one of the rules actually sent in that pass. A cited rule outside the group is dropped — the model cannot invent a regulation.
  2. Quote grounding. A finding's quote must genuinely occur in the reviewed copy (exact, or whitespace-insensitive). Fabricated "offending text" is dropped, and the span shown is always real copy.
  3. Honest severity. The judge is instructed to use P4 "review suggested" whenever it isn't confident a violation is real, rather than inflating an uncertain call into a higher tier.

A real run

warrant-mini check examples/influencer_post.txt (an influencer serum post with no disclosure) produces:

╭──────────────── warrant-mini review ────────────────╮
│ file: examples/influencer_post.txt · 510 chars       │
│ 3 finding(s):   1×P2  1×P3  1×P4                      │
╰──────────────────────────────────────────────────────╯

 P2 · high   Endorsement / testimonial disclosure
 regulation  FTC 16 CFR Part 255
 offending   “They set me up with a code so you can try it too — use LUNA20…”
 why         Reveals a material connection with the brand (a discount code /
             partnership) with no clear "#ad" or "paid partnership" disclosure.
             Hashtags like #skincare do not satisfy the FTC requirement.
 fix         #ad / Paid partnership with GlowLab — they sent me this serum…

 P3 · moderate   Superlative claims requiring substantiation
 offending   “it works instantly”
 why         An objective, verifiable efficacy claim stated as fact with no
             substantiation.

 P4 · review suggested   Superlative claims requiring substantiation
 offending   “the best serum I've ever used”
 why         Framed as opinion, but combined with the efficacy claims a
             reasonable consumer might read it as an implied factual claim —
             flagged for a human to confirm.

And warrant-mini check examples/clean_newsletter.md returns No compliance issues found — including correctly not flagging benign puffery like "we think the new planner is genuinely nicer to use."

Web UI

warrant-mini serve launches a single-page FastAPI app (textarea + results panel) that calls the exact same checker.review() as the CLI — see warrant_mini/web.py.

warrant-mini web UI — the input form with an example loaded

  • POST /api/review { "text": "..." } → the same findings JSON as --json.
  • GET /?example=fintech prefills the textarea with an example.
  • GET /?run=fintech runs the review server-side and returns a rendered results page (works even with JavaScript disabled) — handy for shareable links.

Light and dark themes follow the OS setting.

Networks that inspect TLS

If you're behind a corporate TLS-inspecting proxy (e.g. Zscaler), warrant-mini verifies certificates against your operating system's trust store (via truststore) instead of a bundled CA list — so it works behind such proxies with no extra configuration. See warrant_mini/__init__.py.


Development

uv run pytest        # smoke tests — rule library, judge schema, quote verifier,
                     # input loader (no live API calls)

Swap the model in one place: DEFAULT_MODEL in warrant_mini/checker.py (claude-opus-4-8claude-sonnet-5 for lower cost).


How this was built

An AI-native build: specified once, then implemented end-to-end with Claude Code driving the code, tests, and this README.

  • Time: ~2 hours, single session (CLI + web UI + docs).
  • Model used to build: Claude Code (Opus).
  • Model the app judges with: claude-opus-4-8 (adaptive thinking on).
  • Workflow:
    • Plan-first. Wrote PLAN.md, locked the design decisions (per-rule-group passes, structured outputs, the anti-hallucination contract), and got sign-off before writing code.
    • Then executed the plan top to bottom — models → rule library → checker → CLI → examples → tests → README — validating each layer as it landed.
    • The key design decision is the verification layer: structured outputs guarantee valid shape, so the checker separately verifies each finding is true — dropping any whose rule_id is out of scope or whose quote isn't actually in the copy. This is what keeps the tool from inventing regulations.
    • Live-tested against all three examples, confirming the fintech page lit up with P1s, the influencer post flagged the missing #ad, and the clean newsletter stayed quiet (without false-flagging benign puffery).
    • One real snag: the dev machine sits behind a TLS-inspecting proxy that breaks Python's default certificate verification. Diagnosed it and fixed it properly (verify against the OS trust store via truststore) rather than disabling TLS.
    • Stretch goal landed: the single-page FastAPI UI, including server-rendered ?run= deep-links.
  • What I'd add with more time: per-rule confidence scores; PDF and URL-batch input; a shareable permalink for each review.

License

MIT © 2026 Vinay Vobbilichetty


This is a demo / portfolio piece, not legal advice. The rule library is a small, illustrative subset of real marketing-compliance obligations.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

warrant_mini-0.1.1.tar.gz (23.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

warrant_mini-0.1.1-py3-none-any.whl (25.6 kB view details)

Uploaded Python 3

File details

Details for the file warrant_mini-0.1.1.tar.gz.

File metadata

  • Download URL: warrant_mini-0.1.1.tar.gz
  • Upload date:
  • Size: 23.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for warrant_mini-0.1.1.tar.gz
Algorithm Hash digest
SHA256 f9d4aa86eb5101b9e735dd9f597e5ff09479100e8b3a50e721e26027b5cf13a4
MD5 ef932229475264665890ce42ff4327bb
BLAKE2b-256 0ea2bf4e374fbd2e4bc83a0ff0d58d10cfa4a0f21017c69eab91cfb66de378b8

See more details on using hashes here.

Provenance

The following attestation bundles were made for warrant_mini-0.1.1.tar.gz:

Publisher: release.yml on vinayvobbili/warrant-mini

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file warrant_mini-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: warrant_mini-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 25.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for warrant_mini-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 137c838dd4a0e9450b30e67d1e9af0249353ebfbcfe25b926566758d9020ae43
MD5 6ae948a24d3dfde1d45f311bd248a611
BLAKE2b-256 a49f17a48742b40fc4403404361fcc0bdcfb924f72407599870ebd625b282c05

See more details on using hashes here.

Provenance

The following attestation bundles were made for warrant_mini-0.1.1-py3-none-any.whl:

Publisher: release.yml on vinayvobbili/warrant-mini

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page