Skip to content

Add Drugs.com mirror + task verifiers (site by @boyugou, verifiers by reviewer)#71

Open
Django-Jiang wants to merge 178 commits into
aiming-lab:mainfrom
Django-Jiang:review/drugs_com-verifiers
Open

Add Drugs.com mirror + task verifiers (site by @boyugou, verifiers by reviewer)#71
Django-Jiang wants to merge 178 commits into
aiming-lab:mainfrom
Django-Jiang:review/drugs_com-verifiers

Conversation

@Django-Jiang

Copy link
Copy Markdown
Contributor

Review: Drugs.com mirror (PR #9) — reviewer verifiers + grading contract

Reviewed the PR head in a git worktree, built webharbor:drugs-review, ran on alt ports
(:8207 / 41600-41616). drugs_com is registered at index 16 (port 40016) and applies cleanly
to current main (MERGEABLE — no rebase needed).

Mechanical checks: PASS

  • All 17 sites return 200 (41600-41616)
  • Control plane healthy; drugs_com _health ok
  • Byte-identical reset: md5 = d3d228f3fc0b3b880e149ac35550e3c5 (instance == instance_seed), stable after full task-driving
  • POST /reset-all all ready
  • Assets: .assets-revision pinned to the resolved refs/pr/39 commit (HF discussions/39), a superset of main + drugs_com.tar.gz; fetch_assets.sh succeeds. Maintainer bumps to the merged SHA once HF PR 39 lands.

Visual / functional depth: PASS (Playwright)

Drug detail pages show class + brands + FAQ/dosage/warnings; Interaction Checker, Pill
Identifier, Conditions, Drug Classes, Medical News, Drugs A-Z, and login + My Med List all
render and work. (Home is a text reference layout — no hero images, matching drugs.com.)

Task quality: sound (21 tasks, all read-only info-retrieval)

Every task is answerable from the site and anchored on site-specific facts (drug class, brand
lists, interaction severities, pill imprints, ratings, condition drug lists, catalog membership).
The 21st task (Drugs.com--14) is login-gated and reads the seeded My Med List.

Notes (non-blocking):

  • Some single-drug facts (ibuprofen=NSAID, MNIST-style trivia) are frontier-LLM-guessable, so the
    verifiers require navigating the specific drug/tool page (anti-shortcut nav gate) — a no-op or a
    no-navigation answer FAILs.
  • Search-results pages do surface a drug's class; the verifiers require the detail-page URL
    (/<slug>), so the listing-level leak does not let a shortcut pass.
  • "alcohol" is not a Drug row; the Interaction Checker handles it via a curated lifestyle-rules
    path, so tasks 8 and 19 (…+ alcohol) work correctly (verified live: 8 → 3 interactions/major,
    19 → moderate/lactic-acidosis).

Grading contract authored (reviewer)

  • sites/drugs_com/verify/verify_lib.py + 21 per-task verifiers verify_0.py … verify_20.py.
  • tasks.jsonl backfilled with verifier_path + judge_rubric per row; no answer key.
  • Deterministic-first: navigation evidence + on-page answer match (token/number/count against
    DB-resolved ground truth; "name at least N" tasks require N valid catalog items). LLM/screenshot
    checks anchored on ground truth and SKIP when the LLM is unavailable.

Grading validation

  • No-op (homepage only, empty answer): all 21 verifiers FAIL. Zero false positives.
  • Genuine completion (correct nav + correct answers): all 21 PASS.
  • Wrong answer (wrong availability/severity/pill/rating): FAIL.
  • Shortcut (correct answer, no detail-page nav): FAIL on the nav gate.
  • Byte-identical reset holds after the full run.
  • eval_judge.py --verifier True runs the verifier from verifier_path and writes eval.json
    (confirmed pass=True).

Verdict

Grading contract ready and validated; PR applies cleanly to current main. Ready to merge once the
maintainer bumps .assets-revision to the merged HF SHA after discussions/39 lands.

boyugou and others added 30 commits May 13, 2026 10:00
Adds a complete Flask mirror of drugs.com — the most popular drug
information portal — as a new benchmark site in the WebHarbor suite.

Site covers 81 drugs across 20+ drug classes with real FDA label content
(sourced from the OpenFDA API at seed time), 20 news articles, 22 drug
interactions, and 67 user reviews. Four benchmark users are pre-seeded
(alice.j@test.com / TestPass123!).

Pages implemented:
- Drug detail (/<slug>.html) with Uses/Warnings/Before taking/Dosage/
  Side effects/Interactions/FAQ/Reviews sections and Drug Status sidebar
- Drug A-Z (/drug_information.html, /drugs-a-to-z.html)
- Drug Interaction Checker (/drug_interactions.html, /interaction-checker/)
- Pill Identifier (/pill_identification.html, /pill-identifier.html)
- Drug classes (/drug-classes, /drug-class/<slug>)
- Conditions (/conditions, /condition/<slug>)
- News (/news/, /news/<category>, /news/article/<id>)
- Search, Login/Register, My Med List, Account

21 benchmark tasks in tasks.jsonl covering: drug lookup, interaction
checking, pill identification, A-Z browsing, conditions, drug classes,
FAQ, news, ratings, auth flow, and saved med list.

Registers site in SITES arrays (websyn_start.sh, control_server.py) and
raises EXPOSE range to 40015 in Dockerfile. Seed DB at
instance_seed/drugs_com.db (managed via HuggingFace dataset).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
before_request hook logs in alice.j@test.com on every unauthenticated
request, so all protected routes work without real credentials.
login/register POST always redirect to account — any input is accepted.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Complete visual overhaul matching the real drugs.com site:

Header: white background with colorful logo, A-Z browse strip,
search bar in header, dark navy nav with correct items (Drug
Interaction Checker, Compare Drugs, Pro Edition, More...).

Homepage: "Know more. Be sure." hero, feature icons row (My Med
List / Pill Identifier / Drug Interaction Checker / Drugs &
Medications), A-Z letter grid with Browse by Site Section panel,
popular drug searches tag cloud.

Drug detail: "What is X?" section, reviewer avatar with initials,
tab nav (Uses/Warnings/Before taking/Dosage/Side effects/Interactions/FAQ),
Drug Status sidebar with icons (Rx/OTC badges, pregnancy, CSA, approval,
ingredients), rating bar, related drugs, more-about links.

All other pages (A-Z, interaction checker, pill identifier, news,
conditions list, condition detail, drug class, search, account,
My Med List, login, register) rewritten to match real site layout,
content labels, and structure.

CSS completely rewritten: light/white theme, real drugs.com color
palette, component classes for all new UI patterns.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…remove slug

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…features

- Expand drug catalog from 81 to 212 drugs across all major categories
- Expand drug classes from 57 to 95, conditions from 30 to 49
- Expand interactions from 22 to 127 with realistic severity/descriptions
- Expand news articles from 20 to 64 across FDA Alerts, Drug Approvals, Medical News, Clinical Trials, Health
- Add Pro Edition page, Drug Compare side-by-side, Sitemap, Newsletter
- Add Side Effects search, Drug Warnings/Black Box warnings pages
- Add Terms, Privacy, Contact pages
- Add drug images gallery and drug pricing pages
- Add My Reviews and Account Settings pages
- Fix all broken nav links (Pro Edition, Compare Drugs)
- Fix all broken footer links (Terms, Privacy, Contact, Sitemap)
- Fix account tab links (My Reviews, Settings)
- Add review submission route with rating update
- Add review form on drug detail with rating slider
- Improve interaction checker with severity badges and summary
- Improve search with filters, pagination, condition detection
- Improve pill identifier with shape-aware SVG icons
- Add dark mode support via prefers-color-scheme media query
- Add mobile responsive breakpoints
- Additive seeding: all seed functions add missing rows instead of early-returning

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add whole-function early-return gate to seed_database(). Per AGENTS.md,
per-row gates aren't sufficient because even a no-op commit bumps SQLite
metadata. With Drug.query.count() > 0, all seeding is skipped on
subsequent boots, preserving byte-identity between instance/ and
instance_seed/ after /reset.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…il pages

- Add /<slug>/dosage and /<slug>/side-effects detail routes + templates
- Add drug_classes.html with alphabetical grid and drug counts
- Improve drug_class.html: Rx/OTC column, ratings, related classes sidebar
- Improve condition.html: rating table, sort by rating/name, related conditions
- Improve drug_detail.html: print/share/images/pricing action buttons, dosage
  info sidebar box, enhanced approval history, improved More About links
- Improve drug_az.html: side effects and drug interactions category links
- Add related articles sidebar to news_article.html
- Add condition sort (rating/name) and related conditions to condition_page route
- Add drug_count_val annotation and use drug_classes.html in drug_classes_list
- Add related_classes to drug_class_page route

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…opics

- Add /<slug>/pregnancy page with FDA pregnancy category badge + info
- Add /<slug>/interactions page with severity-sorted interaction table
- Add interaction checker ?drug=<slug> URL param pre-population
- Update drug_detail.html More About links: pregnancy, interactions
- Homepage: add Browse by Health Topic grid, FDA Alerts strip, newsletter signup
- CSS: topic cards, FDA badge, newsletter strip dark navy footer section

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add /<slug>/reviews page with pagination, condition/sort filters, rating bars
- Add /account/subscriptions page with email notification preferences
- Add /account/settings save route (mock, always succeeds)
- Add /account/subscriptions/save route
- Fix account.html Subscriptions tab href
- Improve drug_detail.html reviews section: filter/sort bar, data attributes,
  Was this helpful counter, View all reviews link, client-side JS filtering
- Improve account_settings.html: profile form, privacy toggles, connected apps,
  danger zone delete account

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add format_drug_text Jinja filter to convert raw FDA label text into
  readable paragraphs with sentence grouping and section headers
- Apply filter to drug detail, dosage, side effects templates
- Fix dark mode CSS contrast for drug detail content sections
- Add Related News sidebar to drug detail page
- Add news search and category filter to news index
- Rename news section to Pharmaceutical News and Articles
- Add newsletter subscription sidebar to Drug A-Z page
- Add Symptoms tab to homepage browse section
- Add Symptoms Checker to More... dropdown nav
- Make letter buttons circular (38x38) throughout
- Add feature carousel with < > arrows to homepage

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add JS tab switching to drug detail page (click tab shows only that section)
- Fix drug_az route: pass active_letter/all_letters so A-Z nav renders
- Fix compare_drugs: remove invalid Jinja2 list comprehensions, add drug3
  support, fix action to use url_for, add more comparison rows
- Fix interaction checker datalist to include brand name options
- Fix Pro Edition calculators: BMI, CrCl, body weight now interactive
- Remove alert() from Pro Edition newsletter form (show inline confirm)
- Fix drug detail sidebar: pregnancy link -> drug_pregnancy route,
  remove duplicate More About links, fix approval history link
- Add /my-account.html and /my-med-list.html URL aliases
- Fix news.html hidden field (active_category -> cat)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…cts A-Z

- Add drug thumbnail image to drug detail page header
- Add Drug Images section to homepage with 6 random pill images grid
- Add helpful vote buttons (Yes/No) to reviews with live JS update
- Improve reviews page: rating distribution bars, sort/filter by condition
- Improve search: brand name matching, grouped results (drugs/conditions/news),
  difflib-based "Did you mean?" suggestions
- Improve side effects page: A-Z navigation, 60 curated side effects,
  most commonly searched section, search box

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…icles

- Add generate_drug_prices() with realistic pharmacy price comparison table
  (CVS, Walgreens, Walmart, GoodRx) based on drug tier (OTC/generic/brand)
- Add related drugs section to drug detail page (same drug class, up to 6)
- Add drug interaction count to interactions tab
- Add per-drug warnings page (/<slug>/warnings) with boxed warning section
  and keyword-categorized warning cards
- Add warnings index page with A-Z drug list linking to per-drug warnings
- Improve pill identifier: realistic SVG pill shapes per pill type, imprint
  text displayed on pill, availability badge, size filter removed (unsupported)
- Improve conditions page: top conditions bar, letter filter, drug count badges
- Improve news article: medically reviewed notice, fast facts box, share
  buttons, references section, related articles sidebar improvements
- Improve interaction checker: group results by severity with colored headers,
  summary count banner, drug-food/alcohol interaction sections

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…vements

- Add /api/autocomplete endpoint (drug generic + brand + conditions)
- Wire autocomplete dropdown to header search bar with keyboard nav
- Add utility bar to base.html (Apps/Newsletter/Community/Pro)
- Improve footer with 4 columns: Company, Drugs, Conditions, News
- Improve homepage: popular searches, New Drug Approvals section
- Track recently viewed drugs in session, show in account page and
  drug detail sidebar
- New Drug Approvals section on homepage from news articles

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ovements

- Add symptom checker page with body system categories and condition mapping
- Improve More dropdown: two-column layout with Browse and Tools sections
- Add sort controls to drug class detail page (A-Z, rating, reviews)
- Improve pregnancy page: trimester guidance, bottom line summary box
- Improve dosage page: structured dosage table, max dose warning, storage
- All new pages verified 200

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…cker verified

- Add contextual FAQ generation from drug data (uses/side_effects/availability)
- Render FAQ section as accordion with details/summary elements
- Polish login page: social login buttons, remember me, forgot password
- Polish register page: password strength indicator, terms checkbox
- Improve account settings: profile section, notification prefs, privacy settings
- Docker: all 16 sites return 200, byte-identity reset verified (md5 match)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… checker

- Pro Edition: 4 working clinical calculators (BMI, CrCl, IBW, BSA)
- FDA Safety Alerts sidebar on news page with red-bordered callout box
- Drug detail related news: search by drug/brand name in title/body
- NewsArticle.slug computed property + /news/<slug>-<id> URL aliases
- Symptom checker with 7 body systems and condition mapping

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add /conditions/<slug> alias (was /condition/<slug> singular only)
- Add delete review route and button in account reviews
- Add edit notes functionality in My Med List with textarea toggle
- Add My Stats section to account page (med count, review count, joined date)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… colors

- Add visual star rating (★½☆) to drug header with avg_rating/10 numeric
- Add prominent blue "Add to My Med List" CTA button at top of drug page
- Sync top and sidebar med list toggle buttons via shared JS handler
- Rx badge: blue, OTC badge: green, Rx/OTC badge: purple
- Docker build verified: all 16 sites 200, byte-identity md5 match

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…r counts

- Add CLASS_DESCRIPTIONS for 15 drug classes with mechanism explanations
- Drug class page now shows description, common conditions, notable drugs
- Conditions page: featured conditions box, alphabetical letter sections,
  drug count badges per condition
- Drug A-Z: letter buttons show drug count (A (23)), popular drugs section
- Autocomplete dropdown groups results as Drugs / Conditions sections

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…scriptions

- Homepage browse section: 4 functional tabs (Drugs A-Z, Conditions,
  Drug Classes, Symptoms) with server-side grids toggled by JS
- Search: related searches via difflib close matches
- top_conditions and top_drug_classes passed to homepage
- Docker build verified clean

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tems helper

- Add What to Avoid section (new tab) with drug-class-specific warnings:
  NSAIDs→alcohol/ibuprofen+warfarin, SSRIs→alcohol/MAOIs, opioids→alcohol/driving,
  statins→grapefruit, anticoagulants→NSAIDs/vitamin-K, benzodiazepines→alcohol
- Improve Before Taking section: blue info box + structured bullet list with
  links to interaction checker and pregnancy page
- Add _build_avoid_items() helper keyed by drug class name keywords

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…consumer)

- 4 FDA Alerts: Xeljanz liver injury, fluoroquinolone tendons, testosterone CV,
  ketoconazole hepatotoxicity
- 4 New Drug Approvals: lecanemab Alzheimer's, tirzepatide weight, nirsevimab
  RSV, sickle cell gene therapy
- 4 Clinical Trials: semaglutide CV, pembrolizumab breast cancer, aspirin
  primary prevention, depression combination therapy
- 4 Medical/Consumer: PPIs kidney risk, statin muscle gene, acetaminophen
  pregnancy, generic drug shortages
- Per-title idempotency gate means new articles auto-insert on next fresh seed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…e capsule SVG

- Rewrite drug_images.html: per-shape SVG (round/oval/capsule/etc), radial
  gradient depth, two-tone capsule halves with complementary colors, imprint
  text on pill, drug class and brand names header
- Interaction checker empty state: How it works info box, 6 common interaction
  quick-fill buttons (Warfarin+Aspirin, Fluoxetine+Tramadol, etc.)
- Interaction checker results: allergy reminder callout at top of results

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Print button uses window.print() with @media print CSS hiding nav/sidebar/tabs
- Share button uses Web Share API with clipboard fallback ("Link copied!" feedback)
- Speaker icon near drug name triggers SpeechSynthesisUtterance at rate 0.8

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ovements

- Drug prices: 30/60/90 quantity tabs with deterministic pricing (md5 seed)
- GoodRx-style coupon section with inline code reveal
- "What affects the price?" 4-card info grid
- Account reviews: star rating display, drug name linked, date, Edit button
- Account: saved searches section with 3 example queries

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…r checkboxes

- Drug A-Z: rich drug cards (class badge, Rx/OTC, rating, description excerpt)
- Drug A-Z sidebar: Browse by Drug Type, Popular Drug Classes, Popular Conditions
- Sitemap: 4-column layout (Drug Info, Tools, News, User Tools) with url_for links
- Contact: full contact form with subject dropdown, 911 emergency warning,
  editorial/medical team info, JS submit confirmation
- Newsletter: 4 subscription options (daily/weekly/monthly/trials), recent topics

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…p drugs

- Pro Edition: professional drug lookup widget, clinical monographs grid,
  professional resources grid (interactions, FDA, prescribing, calculators)
- Drug classes list: class data dict with drug count, top 3 drugs, description
- Drug classes template: count badge, description excerpt, top drug links,
  alphabetical grouping
- CSS: .tag-class pill style (blue, rounded)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…unter

- 10-star clickable rating selector with hover/click JS (replaces slider)
- Review form: duration dropdown (1mo/1-6mo/6mo-1yr/1-2yr/2yr+)
- Review form: character counter (0/1000) for body textarea
- Review cards: 5-star visual display, condition/duration pill tags,
  full-month date format, helpful votes retained
- CSS: .star-selector, .star-btn, .review-stars, .review-tag, .char-count

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ntifier UX

- format_drug_text filter: strip FDA section numbers (11 DESCRIPTION),
  IUPAC stereochem names, molecular formula sentences, inactive ingredients,
  crystalline powder descriptions - leaves only clinical content
- Pill identifier: result count banner, improved empty state with numbered
  steps and M367 example, better no-results with Poison Control number,
  "Identify Pill" button text

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
boyugou and others added 30 commits May 14, 2026 06:14
Adds /advertise as an alias for the about page, matching drugs.com's URL structure.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add lecanemab (Leqembi) to DRUGS_DATA so /lecanemab.html resolves
- Add dementia, alzheimers, addiction to CONDITIONS_DATA to fix silent
  skip in seed_drug_conditions() for memantine/naltrexone links
- Fix feature-icons carousel: overflow:hidden -> overflow-x:auto with
  hidden scrollbar so partially-scrolled items are not clipped at edge
- Rebuild instance_seed/drugs_com.db (251 drugs, b32970be)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add /<slug>/reviews/write and /<slug>/reviews/write.html as aliases
for the existing drug_review_new route (/<slug>/reviews/new), matching
common URL patterns agents may navigate to.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add autocomplete=current-password/new-password to the three password
fields on the Account Settings page to satisfy browser hints.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add .claude/ralph-loop.local.md to .gitignore so the loop state file
is not included in PRs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Expose /<slug>/monograph and /<slug>/monograph.html as aliases for
the existing drug_pro_monograph route (/pro/<slug>).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add 60+ more drugs to the seed review list (aspirin, meloxicam,
  diclofenac, acetaminophen, ACE inhibitors, statins, antibiotics, etc.)
  so Similar Medications sections show ratings instead of "No ratings"
- Raise early-return gate from 300 → 1200 reviews so new drugs in the
  list actually get seeded after the initial DB already has reviews
- Raise inner cap from 800 → 2000 to accommodate the larger list
- Call recompute_drug_ratings() after seeding so Drug.avg_rating and
  Drug.review_count stay in sync with the new review rows

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…nhydramine ratings

Extends the seed list with 30+ additional drugs covering commonly-searched
categories: triptans, opioids, sleep aids, tricyclic antidepressants, OTC
supplements, and GLP-1 drugs (tirzepatide/Mounjaro). Also adds laxatives,
vitamins, and opioid antagonists.

Raises the early-return gate from 1200 → 2400 and the inner loop cap from
2000 → 4000 to accommodate the larger list.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace native <datalist> on Compare Drugs inputs with a custom JS
autocomplete that hits /api/autocomplete, eliminating the non-functional
browser ▼ arrow and giving real suggestion dropdowns on keystroke.

Fix my_med_list.html Rx/OTC stat counters: selectattr(..., 'equalto')
failed for drugs with availability 'Rx and/or OTC'. Replaced with
namespace-based loop counters using 'in' membership check, so both
the stats bar at the top and the summary section now show correct counts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Same fix as compare_drugs: removes the browser's native <datalist> ▼
arrow on the drug input and replaces it with a custom dropdown hitting
/api/autocomplete. Selecting a suggestion immediately triggers addDrug()
so the drug tag appears without an extra click. CSS added for the
.checker-ac-drop and .checker-ac-item classes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Each reviewer could only review each drug once but the gate checked total
review count rather than per-pair existence, causing 4x duplicate reviews
when the app restarted with count < 2400. Fix: pre-load existing pairs into
a set, skip already-seeded (drug_id, user_id) combos, gate on reviewer-only
count >= 700. Cleaned DB has 748 unique reviews (from 2520 with dupes).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… section

The Drug Images section on the home page was using a static SVG ellipse with
hardcoded pink fill (#fce6ec) and stroke (#b8526a) for all pills, ignoring
the actual shape and color stored in the DrugImage records. Replace with the
existing render_pill Jinja macro and add .is-236-wrap CSS to size it correctly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…_checker, news_index, search

Flask uses the last @app.route decorator as the canonical URL for url_for(). Routes were ordered
so that legacy/alias paths were last, causing all template links to generate wrong URLs (e.g.,
/dosage-guide instead of /drug_information.html, /drug-identifier.html instead of /pill-identifier).

Reordered decorators so the canonical drugs.com URL is always last on each multi-route function.

Also update CLAUDE.md with complete development notes covering seed DB state, benchmark user
constraints, pill SVG rendering, route canonical URL rules, and HF upload instructions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- symptom_checker canonical: /symptom-checker (was /symptom_checker.html)
- warnings_index canonical: /black-box-warnings (was /boxed-warnings)
- news_category canonical: /news/<category> (was /news/category/<category>)
- More... dropdown: FDA Alerts → /fda-alerts, Drug Warnings → url_for('warnings_index'),
  Dosage Guide → drug_az page, Pregnancy Safety → search for pregnancy warnings

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add /<slug>/price-guide and /<slug>/price-guide.html routes as aliases
  to the existing /<slug>/prices handler (drugs.com uses /price-guide.html)
- Fix news_index ?cat= filter to map slugs to canonical DB category strings
  (e.g. ?cat=medical now matches DB rows stored as "Medical")

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Deduplicate by name (case-insensitive) before adding to drug list
- Skip autocomplete results display if input was already cleared

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds several new pages, fixes broken routes, and polishes all major
page layouts to match drugs.com more closely.

New pages:
- /apps — mobile app download page (fixes utility bar "Apps" link)
- /dosage-guide — general dosage reference page
- /pregnancy-safety — pregnancy drug safety overview
- /emergency-info — emergency contact info page
- /drug/:slug/faq — standalone FAQ page per drug

New components:
- _drug_sidebar.html macro for reusable right-column drug status sidebar
- "Add to My Med List" button in drug detail header (med-list-toggle-top)
  which JS already referenced but the element was missing

Route fixes:
- /conditions/<slug>.html and /condition/<slug>.html now handled (404 fix)
- /drug-classes/<slug>.html and /drug-class/<slug>.html now handled

CSS additions:
- .btn-med-list--header for compact header med-list button
- .drug-header-actions wrapper

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
upstream/main added merriam_webster as the 16th site (index 15, port 40015) plus a booking image fix. This branch independently added drugs_com as a 16th site at the same index/port. Resolve the collision so both coexist:

- websyn_start.sh / control_server.py: SITES order ends '... espn merriam_webster drugs_com'. merriam_webster keeps index 15 / port 40015 (already released upstream); drugs_com moves to index 16 / port 40016.
- Dockerfile: EXPOSE 8101 40000-40016; header comment now 17 sites.
- drugs_com/tasks.jsonl: 21 task 'web' URLs 40015 -> 40016.
- drugs_com/CLAUDE.md: port references 40015 -> 40016.
- Keep the dynamic ${#SITES[@]} readiness/echo lines over upstream's hardcoded 16.

Also pulls in upstream's contributor-contract docs (AGENTS.md / CONTRIBUTING.md): tasks.jsonl ships only the 5 base keys; the reviewer later adds verifier_path + judge_rubric.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- scripts/extract_assets.sh: pack with COPYFILE_DISABLE=1 and pre-strip ._*/.DS_Store so macOS bsdtar stops embedding AppleDouble sidecars (synthesized from com.apple.provenance xattrs) into every <site>.tar.gz. Fixes the 51 ._* files the reviewer found in drugs_com.tar.gz; GNU tar ignores the env var so Linux packing is unaffected. Also benefits any future macOS-packed site.
- sites/drugs_com/tasks.jsonl (task --10): repoint to an FAQ entry that actually exists. The generated ibuprofen FAQ has no 'empty stomach' item (that guidance is in the Dosage section), so the old wording was unanswerable from the FAQ as instructed. Now asks the FAQ 'how should I take ibuprofen' entry (OTC dose + 24h max).
- sites/drugs_com/requirements.txt: drop Flask-WTF (never imported; no CSRF/WTForms/FlaskForm usage). File kept: a per-site requirements.txt is the new_site.py scaffold convention and merriam_webster ships one too; the Dockerfile stays the pinned source of truth.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- .dockerignore: ignore .venv/ (not just venv/). This repo standardizes on uv, which creates .venv; .gitignore already covers it but .dockerignore did not, so a local build leaked the dev venv (~1k files) into the COPY context. Aligns the two ignore files.
- sites/drugs_com/CLAUDE.md: note the asset packer is macOS-safe (drop stale 'PR aiming-lab#13' reference).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Review feedback (aiming-lab#9): the search results page rendered drug_class, brand_names, the CSA-schedule chip, avg_rating/review_count, and a uses/description snippet directly in both the 'Best match' exact-match card and the .drug-card list results — none of it gated behind a click-through to the detail page. At least 4 tasks (drug class, brand names, availability, rating+review count) could be answered from the search page alone.

Stripped all of the above from both card types and from the popular_for_query sidebar (same issue via a brand-name + availability badge). Search results now show only the drug name and navigation links; every field still exists on the detail page, just requires a click to reach.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Auth (review finding: illusory auth)
A before_request hook silently logged every request in as alice regardless
of the /login form, so task 14's sign-in step was a no-op. Removed it and
rewrote login()/register() to do real bcrypt-checked auth, matching the
pattern already used by amazon/allrecipes/bbc_news/github/coursera/
merriam_webster. Verified: wrong password rejected, correct password
succeeds, anonymous access to @login_required routes redirects to /login.

CSRF protection (found during a follow-up auth-security review)
drugs_com was the only one of 17 sites without CSRFProtect(app) -- every
other site (including the two the auth rewrite was modeled on) has it.
Added CSRFProtect, a csrf_token() hidden field to all 19 classic
<form method="post"> submissions across 14 templates, and @csrf.exempt on
the 3 JSON/AJAX-only endpoints (matching the exact pattern other sites use
for their own AJAX endpoints). Re-added Flask-WTF to requirements.txt.

Seed data-quality fixes (review finding + a follow-up DRUGS_DATA sweep)
- suvorexant's availability field held a CSA schedule value ("C-IV")
  instead of "Rx" -- fixed to match every other controlled-drug row.
- Removed 5 brand-as-generic duplicate rows (januvia/jardiance/xarelto/
  xeljanz/xanax), each duplicating an already-correct generic row
  (sitagliptin/empagliflozin/rivaroxaban/tofacitinib/alprazolam). Kept
  janumet/yaz/yasmin -- legitimate distinct real-world branded products.
- 4 pharmacological misclassifications, found by cross-referencing every
  drug's class against that class's own description text: vancomycin
  (glycopeptide, not a Cephalosporin), colchicine (antigout, not a
  Xanthine oxidase inhibitor -- that's allopurinol), glipizide and
  nitrofurantoin (a sulfonylurea and a nitrofuran, neither is a
  Sulfonamide). Added 4 correctly-described classes and reassigned all 4.
- compare_drugs.html: removed 2 popular-comparison suggestions that
  referenced drugs absent from the catalog (orlistat, phentermine,
  glimepiride, insulin detemir).
- Docs (.assets-revision, CLAUDE.md): fixed a stray port reference
  (49015->49016), corrected task 14's description to match tasks.jsonl
  (it's read-only -- lists the med list, doesn't add to it), and updated
  drug/review counts + seed DB md5 for the regenerated seed.

None of the removed/reclassified drugs are referenced by any of the 21
benchmark tasks (grepped tasks.jsonl to confirm). Regenerated
instance_seed/drugs_com.db from scratch and reverified the idempotency
invariant. Full Docker verification: 17/17 sites 200, byte-identical
reset holds, real auth + CSRF verified against the running container with
cookies, all 21 tasks re-audited against the new DB (no regressions).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ran two independent Codex reviews (a different model family than what did the prior work) as a second-opinion pass over the search-leak/auth/CSRF/data fixes: one targeted re-check of those specific changes, one fully open-ended exploration. Both surfaced real issues the Sonnet-based reviews had missed.

CSRF exemption gaps (targeted review)
Two routes were @csrf.exempt despite actually consuming request.form/
request.values from a real browser form or FormData submission, not just
JSON -- meaning the csrf_token already present in those forms was silently
never checked:
- /my-med-list/toggle: removed the exempt; the JSON-only call site
  (drug_detail.html's save/remove buttons) now sends the token via an
  X-CSRFToken header, which Flask-WTF validates for non-form requests.
- /<slug>/review/<id>/helpful: removed the exempt; both FormData call
  sites (drug_detail.html, drug_reviews_page.html) now append csrf_token
  to the FormData alongside the vote.

Open redirect in login() (both reviews independently flagged this)
request.args.get("next") was passed straight to redirect() with no
validation. Added _safe_next_url() -- only allows a single-leading-slash
relative path, rejecting absolute/protocol-relative URLs -- and used it in
place of the raw query param.

Data: 7 drugs referencing undefined drug-class names (open-ended review)
memantine/trimethoprim/lecanemab/ezetimibe/ursodiol referenced class names
with no matching DRUG_CLASSES entry, so drug_class_id silently ended up
NULL for each (Drug.query cls_by_name.get() returns None, no error).
Added the 5 missing classes. umeclidinium and ulipristal referenced
near-miss class name variants ("Bronchodilators, long-acting",
"Progesterone agonists/antagonists") that didn't match anything either --
reclassified both into the existing, pharmacologically-correct classes
(Anticholinergic bronchodilators; Progestogens).

Three smaller bugs (open-ended review)
- 404 handler ordered by the nonexistent Drug.rating_count (typo for
  review_count, silently caught by a broad except and emptying the
  page's "Popular drugs" section).
- drug_side_effects.html and drug_dosage.html both referenced a
  DrugImage.dosage_form field that was never a real column, so the
  intended per-drug value was always the same fallback text. Simplified
  side_effects to the static fallback it already always rendered; dropped
  the dead reference from dosage.html's working shape/strength fallback.
- /api/interaction-check (a JSON endpoint, unreferenced by any template
  and unreachable through the UI -- confirmed no task depends on it, no
  regression risk) silently reported "alcohol" as unrecognized instead of
  resolving it via the same _lifestyle_interactions() helper the main
  interaction-checker UI already uses correctly.

Regenerated instance_seed/drugs_com.db (class assignments changed),
reverified idempotency, and reran the full Docker verification: 17/17
sites 200, byte-identical reset, and the CSRF fix confirmed live against
the running container (toggle rejected without a token, accepted with the
X-CSRFToken header).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ntegrity, XSS)

Ran four independent Codex reviews in parallel, each scoped to a distinct angle: security deep-dive, benchmark task-quality audit, performance/code-quality, and data-integrity/cross-field consistency. Verified every finding against the codebase before acting -- most security and performance findings were confirmed real but assessed as hardening-only with no task impact at this data scale, and left alone; the following were confirmed as genuine bugs and fixed.

Three new answer-leaks (task-quality audit)
Beyond the search-results leak fixed in an earlier round, three more
surfaces let a task be answered without following the path its wording
describes:
- Homepage had a dedicated "New Drug Approvals" box listing article
  titles by recency (directly answering task --11, 'find the most recent
  article in that category'), AND a second, display:none-hidden grid
  section repeating the same titles in raw HTML (dead code, removed). The
  visible box now shows only a category link, no titles. Also excluded
  the New-Drug-Approvals category from the homepage's general "Latest
  Medical News" feed, which was independently leaking the same title via
  its category badge.
- /drug-classes index listed each class's top-3 drugs by name (directly
  answering tasks like --16, 'list 3 benzodiazepines', without opening
  the class page). Removed the list; this also drops an N+1 query
  (104 extra per-class lookups) the performance review flagged separately.
- /search's 'Popular for <query>' sidebar showed up to 8 drug names for
  a matched condition/class (leaking tasks --6/--9/--20 the same way).
  Removed the block and its backing query.

OpenFDA content-mismatch root cause (data-integrity review)
fetch_openfda_label() accepted whatever result the FDA label search
returned with no check that it actually described the queried drug.
Confirmed live: querying "polyethylene glycol" returns a label whose own
openfda.generic_name is ["NAPROXEN"] -- an unrelated drug -- because
FDA's search does fuzzy/tokenized matching. This had silently seeded at
least 4 drugs (polyethylene glycol, tobramycin ophthalmic, zoledronic
acid, insulin aspart) with a completely different drug's
uses/warnings/dosage/side-effects text. Added a match check (the
returned label's own generic name must equal, contain, or token-subset-
match the query) before accepting a label; on rejection, seeding falls
back to the existing synthetic-content generator. Verified the 4 known-
bad drugs are clean post-fix, and swept the full 246-drug table for any
remaining cross-drug duplicate uses/warnings/dosage text -- none found.

XSS escaping inconsistency (security review)
compare_drugs.html and interaction_checker.html both built their
autocomplete dropdown via string-concatenated innerHTML without escaping
the API-provided label, unlike base.html's autocomplete which already
does. Current data source is seeded drug/brand names, not user input, so
not exploitable today, but the pattern is inconsistent and a latent risk
if a future contributor feeds less-trusted text through the same
endpoint. Added the same escapeHtml() used elsewhere to both call sites.

Not actioned, with reasoning
- N+1 query patterns elsewhere (search, condition pages, account pages)
  and the /api/interaction-check O(n*m) brand lookup: real, but at the
  current 246-drug seed size the practical latency impact is negligible,
  and this is a benchmark environment (task correctness, not throughput)
  -- fixing all of them would touch a lot of surface area for no benefit
  to what the benchmark actually measures.
- Canonical URL ordering drift (url_for() resolving to the .html alias
  on a few routes), no visible logout link, Advertise/About linking to
  the same page, hardcoded SECRET_KEY: real but either purely cosmetic,
  a repo-wide convention shared by all 17 sites (not a regression here),
  or not reachable by a UI-only browsing agent.

Regenerated instance_seed/drugs_com.db (seed content changed both from
the leak-fix query changes and the openFDA re-fetch), reverified
idempotency, and reran full Docker verification: 17/17 sites 200,
byte-identical reset, both leak fixes and the CSRF/login flow confirmed
against the running container.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…rd state

Adds a 'Contribution status' section at the top (PR links, current seed md5, what's left) so a reader lands on the current state immediately. Documents the OpenFDA content-integrity guard and the answer-leak guardrails as durable 'do not remove/reintroduce' notes rather than one-off fix logs, since both are load-bearing invariants a future change could silently break. Fixes a stale internal inconsistency (task 14 was described as both 'read-only' and 'read and write' in different sections) and updates the HF asset-upload snippet to push onto the existing PR ref instead of --create-pr, which would open a duplicate.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…unding gotcha

An independent fresh-eyes review round (5 parallel angles: app.py logic,
data-integrity, concurrency, security, templates) found the codebase clean
overall. Two minor items came out of it:

- drug_detail.html had a dead JS click handler for a `#share-btn` element
  that no longer exists on the page (a Share button was apparently removed
  at some point, the handler wasn't). Harmless (guarded by `if (shareBtn)`,
  no console error) but pure dead code — removed.
- avg_rating is a cached column computed with Python's round() (banker's
  rounding), which can differ by 0.1 from SQLite's ROUND(AVG(...)) for
  drugs whose true mean ends in exactly .x5. The site is internally
  consistent (every route reads the same cached column), but a future
  reviewer writing a deterministic verifier by recomputing the average via
  raw SQL could pin a value 0.1 off from what the site actually shows.
  Documented in CLAUDE.md so that doesn't happen.

No task-affecting bugs, no data changes, no reseed needed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants