# Product Requirements Document: fsv-streamlit ## Overview `fsv-streamlit` is a Streamlit web application for Federal Style Validator (FSV), using the `fedstylevalidator` pip package and exposing its full document-checking capabilities via a browser-based UI hosted on Hugging Face Spaces. It replaces `DocumentCheckerToolv1` on Hugging Face, which is a monolithic CLI-only FAA checker with a planned-but-unbuilt Streamlit UI. This project does **not** re-implement any checks — all validation logic lives in FSV. --- ## Goals 1. Deploy a Hugging Face Space that accepts `.docx` uploads and returns FSV findings in an interactive dashboard. 2. Cover all FSV check categories: headings, accessibility, format, structure, terminology, readability, acronym, prose, and document status. 3. Support all FSV document types and run all checks (no pack selection UI — all packs run by default). 4. Provide a download path for results in at least one machine-readable format (JSON) and one human-readable format (DOCX or HTML). 5. Be a drop-in improvement over `DocumentCheckerToolv1` for existing HF Space users — same airplane/FAA audience, better checks, nicer UI. ## Non-Goals - Re-implementing any FSV check logic in this repo. - Supporting file types other than `.docx`. - Authentication, user accounts, or persistent result storage. - Baseline/diff mode, suppression files, or SARIF/JUnit export (can be added later). - The FastAPI backend from FSV — this app calls the Python library directly. --- ## Target Users Federal agency technical writers and document reviewers (primarily FAA) who currently use `DocumentCheckerToolv1` on Hugging Face or the FSV CLI. Non-technical users who need a no-install, browser-based option. --- ## Architecture ### Dependency Model ``` fsv-streamlit/ app.py # Streamlit entry point requirements.txt # fedstylevalidator + streamlit + any extras .streamlit/config.toml # Theme + server config README.md # HF Space metadata (YAML front-matter) + usage ``` `fedstylevalidator` is installed from PyPI (or a local path for dev). No check logic lives in this repo. ### Data Flow ``` User uploads .docx → st.file_uploader → write to NamedTemporaryFile → process_document(file_path, doc_type, visibility_settings, check_packs) → canonical result dict → UI renders findings grouped by category/severity → optional download (JSON / HTML / DOCX) → tempfile cleaned up ``` ### Key FSV API Calls ```python from fedstylevalidator.service import process_document from fedstylevalidator.core.models import VisibilitySettings, Severity, DocumentTypeRegistry from fedstylevalidator.core.outputs import build_canonical_json # Get valid doc types for dropdown doc_types = DocumentTypeRegistry.values() # all registered types # Run checks (all packs, always) result = process_document( file_path=tmp_path, doc_type=selected_doc_type, visibility_settings=VisibilitySettings(**toggle_state), group_by="category", check_packs=None, # None = all packs ) # result["summary"], result["findings"], result["metadata"], result["fun_facts"] ``` --- ## Features ### P0 — Must have for launch **F-01: File Upload** - `st.file_uploader` accepting `.docx` only, **20 MB hard limit** (enforced in app before calling FSV). - Write to `tempfile.NamedTemporaryFile`, clean up after run (try/finally). - Show filename and file size confirmation after upload. - Show `st.progress` bar or `st.spinner` during the FSV call. Because FSV is synchronous, use `st.spinner("Analyzing document…")` as the primary feedback; if FSV ever exposes progress callbacks, wire in `st.progress` then. **F-02: Document Type Selector** - Dropdown populated from `DocumentTypeRegistry.values()`. - Default: "Default"; FSV 0.1.1 exposes the simplified FAA list of "Default", "Advisory Circular", and "Order". - Sidebar placement. **F-03: Check Execution** - All FSV packs run by default; no pack-selection UI exposed to the user. - Pass `check_packs=None` to `process_document()` (runs everything). **F-04: Run Checks Button** - Disabled until a file is uploaded. - Shows `st.spinner("Analyzing document…")` while running. - Calls `process_document()` in a single synchronous call (HF Spaces free tier, no async needed). **F-05: Summary Scorecard** - 4 metric cards: Total Findings | Errors | Warnings | Info. - Pulled from `result["summary"]["issue_count_by_severity"]`. - Overall severity badge (error / warning / info / clean) with color coding. **F-06: Findings Display — by Category** - One `st.expander` per category that has findings. - Each expander header shows: category name + count badge. - Failed categories (errors present) expanded by default; others collapsed. - Inside each expander: table or list of findings with columns: Severity | ID | Message | Location. - Location renders `heading`, `paragraph`, `section` from `FindingLocation` (whichever is non-null). - Severity color-coded: red (error), orange (warning), blue (info). **F-07: Document Metadata Panel** - Collapsible section showing `result["metadata"]`: Title, Author, Created, Modified, LastModifiedBy. **F-08: Readability / Fun Facts** - Render `result["fun_facts"]` as a bulleted list below metadata. **F-09: JSON Download** - `st.download_button` for the canonical JSON (`build_canonical_json(result, ...)`). - Filename: `fsv__.json`. **F-10: External Link Check Toggle** - Sidebar checkbox "Check external links", **default off**. - Helper text: "Verifies that hyperlinks in the document are reachable. May add 30–60 seconds." - When off, pass a `VisibilitySettings` flag or suppress the hyperlink check via FSV's visibility mechanism. - When on, user has explicitly accepted the extra latency. **F-11-p0: Error Handling** - Show `st.error()` if FSV raises (unsupported format, corrupt DOCX, internal error). - Reject files >20 MB before calling FSV with a clear message ("File exceeds 20 MB limit"). - Always clean up tempfile (try/finally). ### P1 — High priority, ship shortly after launch **F-12: Visibility Toggles** - Sidebar checkboxes mapping to `VisibilitySettings` fields (show/hide each category). - Allows users to focus on only the categories they care about. - Re-runs the display (not the check) instantly without re-uploading. **F-13: Findings Display — by Severity** - Toggle between "Group by Category" and "Group by Severity" views. - Uses `result` re-grouped client-side (no re-run needed). **F-14: HTML Download** - Download results as a rendered HTML report from FSV's `render_html_report()`. **F-15: DOCX Report Download** - Download results as a styled `.docx` report from FSV's `save_results_as_docx()`. ### P2 — Nice to have **F-16: Findings Search / Filter** - Text input to filter findings by message text. **F-17: Per-Finding Severity Filter** - Checkbox set: show Errors / Warnings / Info independently. --- ## UI Layout ``` ┌──────────────────────────────────────────────────────────────────┐ │ SIDEBAR MAIN (wide layout) │ │ ────────────────────── ──────────────────────────────── │ │ ✈️ Federal Style Validator [File uploader — .docx, ≤20 MB] │ │ │ │ Document Type [Run Checks button] │ │ [Default ▼] │ │ ─── Results ─── │ │ ─── Options ─── [Total] [Errors] [Warnings][Info]│ │ ☐ Check external links │ │ ⚠ Adds 30–60s runtime ▼ headings (3) │ │ [findings table] │ │ ─── Visibility ─── ▶ accessibility (0) │ │ ☑ Show Readability ▶ terminology (2) │ │ ☑ Show Headings ▶ readability (0) │ │ ☑ Show Terminology ... │ │ ☑ Show Accessibility │ │ ☑ Show Acronyms ─── Document Metadata ─── │ │ ☑ Show Format Title: ... Author: ... │ │ ☑ Show Structure │ │ ☑ Show Prose ─── Fun Facts ─── │ │ • Flesch Reading Ease: 65 │ │ • ... │ │ │ │ [⬇ Download JSON] [⬇ Download HTML]│ └──────────────────────────────────────────────────────────────────┘ ``` --- ## HuggingFace Space Configuration **`README.md` YAML front-matter** (required by HF): ```yaml --- title: FAA Document Checker (FSV) emoji: ✈️ colorFrom: blue colorTo: indigo sdk: streamlit sdk_version: "1.32.0" app_file: app.py pinned: false license: mit --- ``` **`.streamlit/config.toml`**: ```toml [server] maxUploadSize = 50 [theme] primaryColor = "#003087" backgroundColor = "#FFFFFF" secondaryBackgroundColor = "#F0F2F6" textColor = "#1A1A1A" font = "sans serif" ``` **`requirements.txt`** minimum: ``` fedstylevalidator==0.1.1 streamlit==1.56.0 ``` > **Update (April 19, 2026):** FSV 0.1.1 is now the pinned PyPI dependency, so > this repo uses a normal `pip install fedstylevalidator==0.1.1` dependency flow. --- ## Differences from DocumentCheckerToolv1 | Capability | DocumentCheckerToolv1 | fsv-streamlit | |---|---|---| | Checks | 20 FAA-specific | All FSV checks (60+ across packs) | | Document types | 11 FAA types | All FSV registered types | | Agency scope | FAA only | FAA + DOT OGC + general federal | | UI | CLI (no live HF UI) | Full Streamlit dashboard | | Results download | `.txt` report | JSON + HTML + DOCX | | Visibility control | None | Per-category toggles | | Terminology source | `patterns.json` (25 entries) | FSV terminology packs (400+ rules) | | Accessibility | Basic | Section 508 / WCAG | | Readability | 3 metrics | Extended FSV metrics | | Maintainability | Monolithic `main.py` | FSV handles all logic; thin UI layer | --- ## Resolved Decisions | # | Question | Decision | |---|----------|----------| | 1 | FSV pip availability | Published to PyPI and currently pinned as `fedstylevalidator==0.1.1` in `requirements.txt`. | | 2 | NLTK corpora at startup | Unknown — needs a test deploy. If NLTK download hangs the HF Space build, add a `packages.txt` or a startup script that pre-downloads corpora. | | 3 | File size / HF timeout | Hard limit: **20 MB**, enforced before calling FSV. Use `st.spinner` for progress feedback during the synchronous FSV call. | | 4 | Hyperlink check latency | Sidebar toggle **"Check external links"**, default **off**. Users who need it opt in; everyone else avoids the 30–60s penalty and HF timeout risk. | | 5 | Pack install | All packs included in base FSV install. No pack-selection UI; all packs always run (`check_packs=None`). |