feat(phase2): fact/inference labeling, change-driven alerts, admin cleanup

- Add label: cited_fact | inference to LLM brief schema (all 4 providers)
- Inferred badge in AIBriefCard for inference-labeled points
- backfill_brief_labels Celery task: classifies existing cited points in-place
- POST /api/admin/backfill-labels + unlabeled_briefs stat counter
- Expand milestone keywords: markup, conference
- Add is_referral_action() for committee referrals (referred to)
- Two-tier milestone notifications: progress tier (all follow modes) and
  referral tier (pocket_veto/boost only, neutral suppressed)
- Topic followers now receive bill_updated milestone notifications via
  latest brief topic_tags lookup in _update_bill_if_changed()
- Admin Manual Controls: collapsible Maintenance section for backfill tasks
- Update ARCHITECTURE.md and roadmap for Phase 2 completion

Co-Authored-By: Jack Levy
This commit is contained in:
Jack Levy
2026-03-01 17:34:45 -05:00
parent dc5e756749
commit 1e37c99599
12 changed files with 500 additions and 121 deletions

View File

@@ -31,6 +31,10 @@
- [x] Backfill All Actions — admin task to fetch action history for all pre-existing bills
- [x] Notifications (Phase 1) — ntfy dispatch, RSS feed, per-user settings UI, 5-min dispatcher beat task
- [x] Brief Regeneration UI — admin button to delete existing briefs for a bill and re-queue LLM processing. Useful for improving citation/diff logic without a full re-poll. (Backend reprocess endpoint already exists.)
- [x] Follow Modes — `neutral | pocket_veto | pocket_boost` on the `follows` table; FollowButton mode selector with descriptions and tooltips
- [x] Public Browsing — unauthenticated guests browse bills, members, topics, and trending dashboard; AuthModal gates follow/interactive actions; sidebar and nav adapt to guest state
- [x] Draft Letter Generator — collapsible panel on bill detail pages; select up to 3 cited brief points, stance auto-fills from follow mode, recipient derived from chamber, ZIP optional and never stored; calls configured LLM provider
- [x] Bill Text Status Indicators — BillCard shows Brief / Pending / No text badge; backed by a single batch query on the list endpoint
---
@@ -40,8 +44,8 @@
### Phase 2 — High Impact *(can run in parallel after Phase 1)*
- [ ] **Change-driven Alerts**emit `notification_event` from poller/document fetcher on material changes: new doc version, substitute text, committee report, vote scheduled/result. Filter out procedural-only action text. Fan out to ntfy + RSS.
- [ ] **Fact vs Inference Labeling** add `label: "cited_fact" | "inference"` + optional `confidence` field to each `key_point` and `risk` in the LLM JSON schema. Prompt engineering change + BillBrief schema migration. UI: small badge on each bullet (no color politics — neutral labels only).
- [x] **Change-driven Alerts** — milestone keywords expanded (markup, conference, referral tier); topic followers now receive bill_updated milestone events; committee referral events delivered to pocket_veto/boost but suppressed for neutral; all three follow types covered for both tiers.
- [x] **Fact vs Inference Labeling**`label: "cited_fact" | "inference"` on every cited key_point and risk; prompt engineering updated for all providers; "Inferred" badge in citation UI; backfill task for existing briefs.
---
@@ -76,10 +80,9 @@
- [ ] **Source Viewer Option B** — in-app bill text viewer with cited passage highlighted and scroll-to-anchor. Deferred pending UX review of Option A (GovInfo link).
- [ ] **Raw Diff Panel** — Python `difflib` diff between stored document versions, shown as collapsible "Raw Changes" below amendment brief. Zero API calls. Deferred — AI amendment brief is the primary "what changed" story.
- [ ] **Shareable Collection Subscriptions** — "Follow this collection" mechanic so other users can subscribe to a public collection and get its bills added to their feed.
- [ ] Pocket Veto mode (follow stance) — toggle on a bill to treat it as “I dont want this to pass”; adds to watchlist and triggers milestone alerts (committee report-out, calendared, vote scheduled, passed chamber, etc.)
- [ ] Pocket Veto notification rules — alert only on advancement milestones + failure outcomes (failed committee / failed floor / stalled)
- [ ] Follow modes — support Neutral (normal follow) + Pocket Veto now; optional Pocket Boost later
- [ ] UI: FollowButton becomes FollowMode selector (Neutral / Pocket Veto) with explanation tooltip
- [x] Pocket Veto mode (follow stance) — toggle on a bill to treat it as “I dont want this to pass”; adds to watchlist and triggers milestone alerts
- [x] Follow modes — Neutral + Pocket Veto + Pocket Boost; FollowButton is a mode selector with explanation tooltips
- [ ] Pocket Veto notification rules — alert only on advancement milestones + failure outcomes (failed committee / failed floor / stalled) — notification dispatcher needs to filter by follow_mode
### PocketVeto function
@@ -162,3 +165,51 @@ Then alert rules can be:
- pocket_boost: “action points” + milestones
Yes — thats a solid idea **if its done as a “welcome + how it works” nudge**, not an annoying pop-up that blocks the UI.
A toast can work, but for a first-time user youll usually get better results with a **dismissible banner** or a **one-time “welcome” card** on the dashboard, because:
* toasts disappear (people miss them)
* first-run onboarding usually needs at least one click (“Got it” / “Start here”)
### Best pattern (low effort, high impact)
**First visit → show a dismissible Welcome card/banner** (top of dashboard) with:
* 1 sentence purpose
* 3 bullets of key features
* 2 buttons: **“Add my first follow”** and **“See a demo bill”**
* “Dont show again” checkbox (or implicit on dismiss)
You can still use a toast, but make it:
* sticky until dismissed
* or paired with a banner/card
### What it should say (copy you can paste)
**Title:** Welcome to PocketVeto
**Body (tight):**
* Follow bills, members, or topics (low-noise)
* See *what changed* in plain English
* Verify every claim with **Back to Source** citations
**Buttons:** “Add a follow” | “Load demo”
### Implementation detail (no creepy tracking)
Store a simple flag:
* `localStorage.setItem("pv_seen_welcome", "1")`
Dont store it server-side unless you already have user accounts and its part of preferences.
### Backlog item (checkboxes)
* [ ] First-visit welcome UI (banner/card + optional toast)
* [ ] Dismiss + “dont show again” (localStorage)
* [ ] CTA: Add first follow
* [ ] CTA: Load demo data (optional)
* [ ] Link: “How it works” page/modal (optional)
If you tell me your UI stack (sounds like Next.js + shadcn/ui), I can give you a drop-in component for a clean welcome card + toast behavior.