"""``scraper.dashboard`` — spec §5 (UI build, task t_b38e9af2). An anonymous + logged-in legislative dashboard served over the stdlib HTTP server (no heavy framework), backed by the correlation lane's relational DB (``bills`` / ``committees`` / ``members`` / ``committee_members`` / ``bill_committees`` + the flat ``daily_file_records`` view) and the LLM lane's ``bill_tags`` table. Submodules ---------- * :mod:`scraper.dashboard.ranking` — pure float-to-top ranking + ``hearing_sort`` + ``matched[]`` transparency. No I/O. * :mod:`scraper.dashboard.context` — :class:`RelevanceContext` builder (prefs -> watched-author / watched-committee / opt-in tag sets). * :mod:`scraper.dashboard.data` — read-only DB access (bill events, tag cloud, legislators, districts). * :mod:`scraper.dashboard.prefs` — ``user_prefs`` + watch/topic persistence + a *local/minimal* auth placeholder (D1). * :mod:`scraper.dashboard.resolve` — ZIP/address -> district -> legislators (two-tier, D2), with confidence. * :mod:`scraper.dashboard.api` — request handlers producing the frozen API_CONTRACT.md shapes / errors / empty states. * :mod:`scraper.dashboard.server` — stdlib ``http.server`` + static frontend. * :mod:`scraper.dashboard.dashboard_cli` — guardedly-wired ``dashboard`` CLI subcommand. FROZEN CONTRACTS honoured (task t_b38e9af2 / parent t_21cd58a9): * Python 3.9.6, stdlib only — no new third-party dependency (the server uses ``http.server`` / ``urllib``, mirroring the LLM lane's degradation posture). * Field names match ``design/API_CONTRACT.md`` verbatim. * The ranking model is DESIGN_DASHBOARD §4: a bill floats to the top iff ``author ∩ watched_legislators ≢ ∅`` OR ``bill.tags ∩ opted_in_tags ≢ ∅``. * Never fabricate: a committee with no roster produces no committee membership (inherited from the correlation lane); the committee-of-watched path simply does not fire for such bills (degrades to author + tag only). """ from __future__ import annotations __all__ = ["ranking", "context", "data", "prefs", "resolve", "api", "server"] #: Default personalization band size (DESIGN_DASHBOARD §4: "top N = 10"). PERSONAL_BAND_N = 10