{"schema_version":"1","site":"https://decosa.ai","id":"promo-claims-check","num":"22","name":"Promotional-claims pre-check","tool_name":"Pre-check promo claims for MLR","short":"Promo claims","blurb":"Checks every claim in a drug, device or supplement promotional piece against its label and references before MLR review: unsupported or off-label claims, missing fair balance, comparisons without head-to-head data, and supplement disease claims. Returns a signed pre-review packet.","status":"live","labels":{"industry":["healthcare","compliance-trust"],"job":["review"],"input":["text"],"deploy":["hosted","selfhost"],"status":"live","output":["text","record"],"data":["confidential"],"hardware":"gpu-96","licence":"permissive"},"industries":["healthcare","compliance-trust"],"runs_in":["hosted","selfhost"],"part_of":[],"built_from":["grounding","signed-record"],"models":"Qwen3.8-27B","where":"Self-host for unpublished data; hosted for public labels","hardware":"1× RTX PRO 6000 (96 GB) for the model; extraction, rules and the packet run on CPU","final_artifact":"An annotated MLR pre-review packet and a signed JSON record of every finding.","self_host_first":false,"verification":{"receipt_coverage":"full","summary":"Receipt per model call; signed packet","manual_qa":{"hosted":{"date":"2026-09-25","result":"pass","p50_ms":3917,"p95_ms":null,"runs":null,"receipts_per_run":14,"cost_per_run_usd":0.0225},"selfhost":{"date":"2026-09-25","result":"pass","method":"fresh clone, compose up, sample against local model servers","notes":"Method: a fresh clone of decosa-api main, the api image built from it, the compose file from this prompt, then the prompt's smoke steps and the nightly smoke module, against the already-running local Qwen3.8-27B vLLM. Verified on 25 Sep 2026: images build, services start, sample passes end to end against local model servers equivalent to the documented ones; model-server startup itself not re-verified. Planted metformin piece: status issues with every expected finding (contradicted HbA1c, off-label weight and heart claims, comparative, fair balance, boxed warning); the compliant piece came back clean; the packet verifies and a changed finding fails."},"known_limits":["Speed depends on load: a 7-14 sentence piece took 4-10 s on a quiet GPU and 30-35 s while the shared GPU was busy (25 Sep 2026).","Text only: type size, placement and contrast are not assessed. Tables flattened to text can be misread.","The eval's planted problems are blatant ones; subtle violations are not measured yet. A person reviews every finding."],"nightly_covers":null},"nightly":"https://api.decosa.ai/verify/status"},"eval_summary":{"metrics":[{"name":"Planted problems caught (all categories)","value":"20 / 20","unit":null,"n":20,"split":"test","note":"Repeat run of the same test split: 20 / 20. Dev: 11 / 11."},{"name":"Piece-level problems caught (fair balance, DSHEA)","value":"2 / 2","unit":null,"n":2,"split":"test","note":null},{"name":"Unplanted sentences with an issue (false positives)","value":"1 / 63 (1.6%)","unit":null,"n":63,"split":"test","note":"Repeat run: 1 / 63. Dev: 2 / 31."},{"name":"Unplanted sentences with any finding (issue or check)","value":"3 / 63","unit":null,"n":63,"split":"test","note":"Repeat run: 4 / 63."},{"name":"Compliant pieces with no issue","value":"3 / 4","unit":null,"n":4,"split":"test","note":null}],"dataset":"12 synthetic promotional pieces for a fictional distributor (4 dev, 8 test), checked against public FDA labels (openFDA), NIH Office of Dietary Supplements fact sheets and synthetic spec sheets. Each product has one piece with planted problems and one written to comply.","held_out":true,"caveats":["The planted problems are blatant and were written by the same person who built the checker; subtle problems are not measured.","Synthetic copy only; the false-positive rate is on copy written to comply, and real copy should bring more check-level noise.","Text only: visual prominence of risk information is not measured, and devices were not evaluated.","Greedy decoding on a shared server is not bit-for-bit repeatable; one recording run flagged a compliant piece.","One change was made after the first dev run; the test split was never used to change anything."],"date":"2026-09-25","doc_url":"https://decosa.ai/metrics/evals/promo-claims-check"},"stack":{"summary":"Send a promotional piece and its reference pack: the label or prescribing information, the cited studies, spec sheets and, optionally, the approved claims matrix. Each sentence is checked against the references by the grounding module, which returns the supporting span. A second receipted call types the claim: off-label against the approved indication, comparative or superlative, and disease or structure/function for supplements. The whole piece is then checked for fair balance, the boxed warning and the DSHEA disclaimer. The output is an annotated MLR pre-review packet, plus a signed record of hashes and findings. It is a pre-check that shortens review, not a replacement for it.","tagline":"Every claim in a drug, device or supplement piece checked against its references before MLR review, with the span behind it and what is wrong.","deployment":"hosted-or-self-host","regulatory_note":"Checked 25 Sep 2026. This is a pre-check that helps a medical-legal-regulatory (MLR) committee; it approves nothing, and the company and its reviewers stay responsible for every piece. What it checks against: FDA's prescription drug advertising rules (21 CFR 202.1: not false or misleading, fair balance of benefit and risk, only uses in the approved labeling), which FDA's Office of Prescription Drug Promotion enforces; FDA's 2018 guidance on communications consistent with the FDA-required labeling; the DSHEA rules for supplement claims (21 CFR 101.93: structure/function claims need the disclaimer in 101.93(c), disease claims are not allowed); and the FTC's Health Products Compliance Guidance (December 2022), which expects competent and reliable scientific evidence that fits each claim. It reads text only, so the visual prominence of risk information is not assessed, and a claim the references support can still be misleading in context. Findings come from a language model and can be wrong in both directions (see the eval). Unpublished study data and pre-launch pieces should stay on your own hardware: self-host. The hosted demo keeps nothing (piece and references stay in memory for the request; the packet holds hashes; logs carry counts) and should be used with public labels and synthetic or published copy only. Model licence: Apache-2.0 (Qwen3.8-27B). Not legal or regulatory advice.","components":[{"id":"precheck","role":"Pre-check: sentences, label sections, rules, findings, the packet (no model; CPU)","name":"decosa-api promo module (decosa_api/verticals/promo) with the grounding module (decosa_api/verticals/grounding)","hf_repo":null,"license":"AGPL-3.0-or-later","params":null,"quant":null,"vram_gb":0,"memory_gb_estimate":null,"engine":"Python 3.12; rule sentence splitter, BM25 over reference spans for packs over 24,000 characters, regex checks for the DSHEA disclaimer and a pointer to full prescribing information","receipt_coverage":"partial","in_hosted_demo":null,"tiers":["standard"],"alternative_to":null},{"id":"model","role":"Grounding judge, claim reviewer, head-to-head and fair-balance checks","name":"Qwen3.8-27B (NVFP4)","hf_repo":"nvidia/Qwen3.8-27B-NVFP4","license":"Apache-2.0","params":"27.8B","quant":"NVFP4 (MLP NVFP4, GDN/attention FP8) + FP8 KV cache; MTP head, 3 draft tokens","vram_gb":20,"memory_gb_estimate":null,"engine":"vLLM 0.29.0, temperature 0, thinking off, prefix caching","receipt_coverage":"strong","in_hosted_demo":true,"tiers":["standard"],"alternative_to":null},{"id":"vision","role":"Layout reader for visual prominence (alternate)","name":"Qwen3.8-27B vision input","hf_repo":"nvidia/Qwen3.8-27B-NVFP4","license":"Apache-2.0","params":"27.8B","quant":"NVFP4","vram_gb":20,"memory_gb_estimate":null,"engine":"vLLM with image input","receipt_coverage":"none","in_hosted_demo":false,"tiers":["alternates"],"alternative_to":null}],"tiers":[{"id":"standard","label":"Standard · one GPU for the model (hosted demo)","summary":"Qwen3.8-27B does the grounding, the claim review and the head-to-head and fair-balance checks, each in its own receipted call. This is what the hosted API runs.","components":["precheck","model"],"hardware":"1x RTX PRO 6000 96 GB (measured) or 1x RTX 5090 32 GB (estimate)","quality_evidence":[{"metric":"Planted problems caught, held-out test (unsupported, off-label, comparative, disease)","value":"20 / 20 (9/9, 3/3, 3/3, 5/5), same in a repeat run","source":"docs/evals/promo-claims-check.md: 8 synthetic pieces on 3 public labels and 3 NIH fact sheets"},{"metric":"Piece-level problems caught, test (fair balance, DSHEA disclaimer)","value":"2 / 2","source":"docs/evals/promo-claims-check.md"},{"metric":"False positives, test: unplanted sentences with an issue / with any finding","value":"1 / 63 (1.6%) / 3-4 of 63","source":"docs/evals/promo-claims-check.md, two runs"},{"metric":"Dev split (the only split used for a change)","value":"11 / 11 caught; 2 / 31 unplanted with an issue","source":"docs/evals/promo-claims-check.md"}],"latency_note":"measured: under a minute to over a minute per piece through the shared gateway.","in_hosted_demo":true,"receipt_coverage":"strong","receipt_note":"Every model call is a separate gateway call with a gateway-signed receipt; the signed packet lists them all.","hosting":null}],"alternates":[{"id":"vision","label":"Layout-aware check","components":["vision"],"hardware":"1x RTX PRO 6000 96 GB (estimate)","use":"Read the rendered page as well as its text with the 27B's own vision input, so fair balance can account for type size and placement. Not built.","status":"not built"}],"services":[{"name":"decosa-api","port":8445,"image":"${DECOSA_REGISTRY}/decosa-api:<tag>","purpose":"GET /promo/info, /promo/samples; POST /promo/check (SSE or JSON), /promo/verify. Keeps no text."},{"name":"vLLM (model)","port":8114,"image":"vllm/vllm-openai@sha256:c2914767605584b6d8f45686b82de173ecc99e781897aa3d0a66dacd72c51ae1","purpose":"Qwen3.8-27B NVFP4 behind our gateway (hosted) or called directly (self-host)."}],"tools":[{"name":"openFDA drug label API / DailyMed","url":"https://open.fda.gov/apis/drug/label/","license":"Public domain (US government data; openFDA terms)","purpose":"The metformin, atorvastatin and lisinopril labels used in the demo and eval (section excerpts; set ids in scripts/promo_cases.py)."},{"name":"NIH Office of Dietary Supplements fact sheets","url":"https://ods.od.nih.gov/factsheets/list-all/","license":"Public domain (US government work)","purpose":"Magnesium, vitamin D and omega-3 health-professional fact sheets as supplement references."},{"name":"scripts/promo_eval.py and docs/evals/promo-claims-check.md","url":null,"license":"Apache-2.0","purpose":"12 synthetic pieces with planted violations (dev and test split), the scoring and the results."},{"name":"POST /promo/verify","url":null,"license":"Apache-2.0","purpose":"Checks a packet's signature against this server's key and, if you send them, the hashes of the piece, the references and the Markdown packet. The console also checks the signature in your browser with WebCrypto."}],"hardware":[{"tier":"1x RTX PRO 6000 Blackwell 96 GB","fits":true,"notes":"Measured on our server: the hosted demo and the eval ran on this card, shared with other services."},{"tier":"1x RTX 5090 32 GB","fits":true,"notes":"Estimate: Qwen3.8-27B NVFP4 needs about 20 GB of weights plus KV cache; not run for this tool. Reference packs of 20k+ characters make long prompts, so keep prefix caching on."}],"latency":[{"lane":"one piece of 7-14 sentences, hosted gateway route","typical_ms":35000,"source":"measured on our server 2026-09-25: 25-77 s per piece over 12 eval pieces and 8 demo recordings, shared gateway and GPU"},{"lane":"model calls per piece","typical_ms":null,"source":"measured 2026-09-25: about 20 calls and 1.6k generated tokens per piece (156 calls, 13.0k tokens for 8 test pieces)"}],"benchmark":null,"notes":["The planted problems in the eval are blatant ones, written by the same agent that built the checker; 20 of 20 caught means obvious problems are caught, not that subtle ones are. The next eval should use real OPDP untitled and warning letters, which are public.","The one test false positive, in both test runs: a trial result in a population the label covers was called off-label. On copy written to comply, 1 of 63 sentences drew an issue and 3-4 drew a check.","Tables flattened to text are a weak spot: while recording the demo, the compliant metformin piece once had a head-to-head sentence marked contradicted because the judge misread the label's flattened table (1 of 4 runs of that piece).","Rx drugs and devices: a comparative claim needs head-to-head evidence in the references (a separate receipted call checks the cited passages). Supplements: a comparison the references state outright is backed, since the FTC asks for evidence that fits the claim rather than a head-to-head trial.","The signed packet holds hashes, offsets, finding codes and receipt ids; the Markdown packet that quotes the copy is returned to you and its hash is in the signature."]},"buyer_facts":[{"label":"Data retention","value":"Nothing stored: the piece and references live in memory for the request. The signed packet holds hashes, offsets, finding codes and receipt ids, never the copy."},{"label":"What leaves the box","value":"Hosted: every model call goes through our gateway to the GPU serving Qwen3.8-27B, and its receipt (hashes, token counts, no text) is kept by the gateway and this API. Self-hosted on the direct route: nothing leaves the box."},{"label":"Input formats","value":"Text only: piece up to 8,000 characters and 40 claim sentences; up to 10 references (label, studies, other) and 200,000 characters; up to 60 claims-matrix entries. Extract PDF text yourself."},{"label":"Typical run","value":"The metformin sample: a dozen or so model calls and a few cents at the gateway list price; the supplement sample about the same. Each run shows its own measured cost."}],"hosted_now":{"needs":["qwen3.8-27b"],"off":[],"live_by_default":true,"live_status":"https://api.decosa.ai/status"},"data_handling":{"page":"/data#promo-claims-check","self_host":{"level":"confidential","leaves":"nothing","summary":"Runs on your machine; nothing is sent to Decosa or a third party by default."},"hosted":{"level":"operator-processed","demo_only":false,"summary":"TLS to Decosa's server, then decrypted and processed by Decosa's API server, with the open models run by NEAR AI through OpenRouter, with Reka AI as the only fallback under Decosa's account.","gpus":"operator-contracted","third_parties":[],"retention":"Nothing stored: the piece and references live in memory for the request. The signed packet holds hashes, offsets, finding codes and receipt ids, never the copy.","used_for_training":false,"encrypted_while_processed":false},"sealed_tier":{"applies":false,"note":"The sealed tier (raw chat only, never use-case pipelines) is paused at launch (/docs/sealed-tier)."},"external_calls":[]},"console":{"href":"/tools/life-sciences/promo-claims-check","input":"promo","lanes":[{"id":"claims","title":"Claims","kind":"list"},{"id":"piece","title":"Whole piece","kind":"markdown"},{"id":"packet","title":"Pre-review packet","kind":"json"}],"samples":[{"n":1,"id":"metformin-planted","title":"Metformin planted","deep_link":"/tools/life-sciences/promo-claims-check?sample=1&autorun=0"},{"n":2,"id":"metformin-compliant","title":"Metformin compliant","deep_link":"/tools/life-sciences/promo-claims-check?sample=2&autorun=0"},{"n":3,"id":"magnesium-planted","title":"Magnesium planted","deep_link":"/tools/life-sciences/promo-claims-check?sample=3&autorun=0"},{"n":4,"id":"magnesium-compliant","title":"Magnesium compliant","deep_link":"/tools/life-sciences/promo-claims-check?sample=4&autorun=0"}],"deep_link_params":{"sample":"1-based index into samples, or a sample id","autorun":"1 = start the run once the sample is loaded; 0 (default) = only preselect","reduce-motion":"1 = turn off animations"}},"api":{"base":"https://api.decosa.ai","contract":"/api/contract.json","contract_markdown":"/api/contract.md","reference":"/docs/api","keys":"/account/keys"},"prompts":{"hosted":"/prompts/promo-claims-check-hosted.md","selfhost":"/prompts/promo-claims-check-selfhost.md","assemble":"/prompts/promo-claims-check-assemble.md","mac":"/prompts/promo-claims-check-mac.md"},"rehearsal":{"bundle":"/samples/promo-claims-check.zip","bundle_url":"https://decosa.ai/samples/promo-claims-check.zip","folder":"/samples/promo-claims-check/","expected":"/samples/promo-claims-check/expected.json","files":["/samples/promo-claims-check/expected.json","/samples/promo-claims-check/inputs/piece.md","/samples/promo-claims-check/inputs/product.json","/samples/promo-claims-check/inputs/references.json"],"bytes":5529,"checks":["the piece comes back with issues","at least two disease claims are flagged","the planted 'cure insomnia' sentence is flagged as a disease claim","the missing DSHEA disclaimer is flagged","the signed packet verifies","the packet matches the MLR Markdown packet","the packet matches the piece","the packet matches the references","a packet with its status changed to clear no longer verifies","every model call has a signed receipt"],"licence":"Synthetic promotional copy for the fictional brand Fernhill, written for Decosa. Reference: NIH Office of Dietary Supplements magnesium fact sheet (US government work, public domain) plus a synthetic product spec. Part of decosa-api, which will be released under AGPL-3.0-or-later; until then the source is on request.","about":"A product page for a fictional magnesium supplement, checked against the public NIH fact sheet and a synthetic spec. It makes three disease claims (insomnia, blood pressure, migraines) and has no DSHEA disclaimer, so the pre-check must flag them, and the signed MLR packet must verify and catch a changed status.","run":{"containers":"docker compose exec api python scripts/rehearse.py promo-claims-check","checkout":"python scripts/rehearse.py promo-claims-check --bundle promo-claims-check.zip --base-url http://127.0.0.1:8445","mac":".venv/bin/python scripts/rehearse.py promo-claims-check"},"guidance":"Set up with a coding agent (we recommend Claude Code with Claude Opus 5.5; any capable coding agent works) on mock data only, run the rehearsal until every check passes, then run your own data locally yourself. Never give the agent real data during setup."},"hardware_fit":{"check":"/self-host/hardware?use=promo-claims-check","data":"/api/hardware.json","tiers":[{"id":"standard","gpu_gb":57.6,"basis":"stack","unknown":[]},{"id":"alternate-vision","gpu_gb":57.6,"basis":"stack","unknown":[]}],"mac":{"fit":"full","memory_gb":32}},"links":{"page":"/tools/life-sciences/promo-claims-check","json":"/use-cases/promo-claims-check.json","metrics":"/metrics/promo-claims-check","console":"/tools/life-sciences/promo-claims-check","console_sample":"/tools/life-sciences/promo-claims-check?sample=1&autorun=0","stack":"/tools/life-sciences/promo-claims-check#stack","try_live":"/tools/life-sciences/promo-claims-check","watch":"/tools/life-sciences/promo-claims-check","build":"/tools/life-sciences/promo-claims-check#build","self_host":"/tools/life-sciences/promo-claims-check#self-host","prompts":{"hosted":"/prompts/promo-claims-check-hosted.md","selfhost":"/prompts/promo-claims-check-selfhost.md","assemble":"/prompts/promo-claims-check-assemble.md","mac":"/prompts/promo-claims-check-mac.md"}}}