# AI Working Notes Running decisions and context for Claude Code sessions. Update as work progresses. ## Current Status Snapshot - Implemented: `app.py`, `requirements.txt`, `.streamlit/config.toml`, `README.md`, and `src/fsv_streamlit/`. - Still pending: first real Streamlit startup smoke test, first Hugging Face deploy, automated tests, and CI. - Note: older sections below contain scaffold-era notes and do not fully reflect the current implementation. ## 2026-04-19 Packaging Update - `fedstylevalidator` 0.1.1 is the current pinned PyPI dependency. - `requirements.txt` and `requirements-space.txt` now pin `fedstylevalidator==0.1.1` and `streamlit==1.56.0`. - Synced the Streamlit document-type selector with the FSV 0.1.1 simplified frontend behavior: `Default` is selected by default and shown before the dedicated `Advisory Circular` and `Order` profiles. - The Hugging Face deployment path remains Docker-based and installs the published PyPI package during image build. ## 2026-04-11 Packaging Update - `fedstylevalidator` 0.1.0 was published to PyPI on April 11, 2026. - `requirements.txt` initially pinned `fedstylevalidator==0.1.0` and `streamlit==1.56.0`. - The Hugging Face deployment path no longer needs a private Git URL or build secret and is back on the standard Streamlit Space configuration. ## 2026-04-11 Upload 403 Investigation - Investigated a Hugging Face upload failure surfaced in the browser as `AxiosError: Request failed with status code 403`. - This error shape indicates the browser-side Streamlit client is being denied while posting the upload to the Streamlit server, before the app reaches the `fedstylevalidator` analysis call. - The working hypothesis is Streamlit XSRF protection rejecting the proxied upload request in the Docker Space deployment path. - Mitigation applied: explicitly disable XSRF protection in both `.streamlit/config.toml` and the Docker `CMD`. - Added `tests/test_deployment.py` to lock in that deployment requirement. ## 2026-04-11 Docker Context Tightening - Tightened Hugging Face Docker image inputs so the runtime image only copies `app.py`, `.streamlit/`, and `src/` after dependency installation. - Expanded `.dockerignore` to exclude non-runtime repository content such as agent notes, planning docs, tests, caches, and local development metadata. - Added deployment tests that assert the Dockerfile does not use a broad `COPY . .` step and that `.dockerignore` continues to exclude non-essential files. ## 2026-04-11 Style Guide Tab - Added a new Streamlit `Style Guide` tab alongside the validator workflow. - The tab reads the checks reference from `fedstylevalidator.core.docs.render_checks_reference()` when available so the content stays aligned with the installed validator version. - Added a local development fallback to `C:/dev/FedStyleValidator/docs/checks-reference.md` if the package-level docs renderer is unavailable. - Extended UI tests and Streamlit test doubles to cover the new tab. ## 2026-04-11 Rules Reference Tab - Added a third Streamlit tab, `Rules Reference`, alongside `Document Checker` and `Style Guide`. - The tab reads from `fedstylevalidator.core.docs.render_rules_reference(RULES)` when available so the content reflects the installed FSV rule registry. - Added a local development fallback to `C:/dev/FedStyleValidator/docs/rules-reference.md` if the package-level renderer is unavailable. ## 2026-04-11 Branding Cleanup - Updated repo-facing branding to prefer `Federal Style Validator (FSV)` on first reference and `FSV` afterward. - Kept `fedstylevalidator` only where the actual Python package name or import path must be referenced. ## 2026-04-10 Implementation Update - Added the first runnable Streamlit app scaffold: `app.py`, `requirements.txt`, `.streamlit/config.toml`, `README.md`, and `src/fsv_streamlit/`. - Root `app.py` is now a thin bootstrap that adds `src/` to `sys.path`, sets Streamlit page config, and calls `fsv_streamlit.ui.run_app()`. - The FSV boundary now lives in `src/fsv_streamlit/fsv_client.py` and calls `fedstylevalidator.service.process_document(...)`. - Downloads are centralized in `src/fsv_streamlit/downloads.py` and canonical JSON is generated with `build_canonical_json(...)`. - The current FSV service result does not include a top-level `summary`; the UI derives metrics from the canonical JSON payload. - The external-link checkbox is present in the sidebar, but the current FSV API does not expose a link-only suppression flag, so the control is informational for now. - Verification completed: `ruff check .` and `python -m py_compile ...`. - Hugging Face deployment temporarily moved to a Docker Space because the private `FedStyleValidator` repository could not be installed anonymously by the built-in Streamlit Space builder. That workaround is obsolete now that the initial `fedstylevalidator` PyPI package was published. - Added an initial pytest suite under `tests/` that stubs `streamlit` and `fedstylevalidator` so the wrapper can be tested without the real dependency stack. Coverage now includes upload validation, temp-file handling, export generation, visibility filtering, and the FSV client boundary. ## Key Decisions - **FedStyleValidator** is a pip dependency (not reimplemented here). All check logic lives there. - **No pack-selection UI** — all FSV packs run by default (`check_packs=None`). - **20 MB file size limit** enforced in app before calling FSV. - **Hyperlink check** is off by default (sidebar toggle) due to 30–60s latency risk on HF Spaces. - **FSV packaging** — use the published PyPI package and pin `fedstylevalidator==0.1.1`. - **HF deployment path** - use the standard Streamlit Space configuration now that the dependency is public. ## Architecture - `app.py` — Streamlit entry point - `requirements.txt` — `fedstylevalidator==0.1.1` + `streamlit==1.56.0` - `.streamlit/config.toml` — theme (FAA blue `#003087`) + 50 MB upload limit - `README.md` — HF Space YAML front-matter + usage docs ## FSV API Entry Point ```python from fedstylevalidator.service import process_document from fedstylevalidator.core.models import VisibilitySettings, DocumentTypeRegistry result = process_document(file_path, doc_type, visibility_settings=VisibilitySettings(), check_packs=None) # result["summary"], result["findings"], result["metadata"], result["fun_facts"] ``` ## Status - [x] PRD written (`PRD.md`) - [x] Repo scaffolded (CLAUDE.md, .claudeignore, .gitignore, .claude/settings.json) - [ ] `app.py` — main Streamlit app - [ ] `requirements.txt` - [ ] `.streamlit/config.toml` - [ ] `README.md` (with HF Space front-matter) - [ ] First HF Space deploy + NLTK startup test ## AI Reliability Architecture Implementation Plan ## Reliability Findings - The repository is currently a scaffold. Reliability requirements are described in `PRD.md`, but almost none of them are enforced in code yet. - The documented runtime shape is a root `app.py` that calls `fedstylevalidator.service.process_document()` directly. If implemented literally, that will couple UI rendering, file I/O, config loading, error handling, provider calls, and download generation in one module. - There is no runtime package, no tests, no CI workflow, no release checklist, no typed contracts, and no observability layer. - The only existing quality control is local Ruff configuration in `pyproject.toml` plus a local Claude hook. That is useful for formatting, but it is not a repository-level reliability gate. - No circular imports or oversized runtime modules exist yet because the app code has not been created. The main architectural risk is allowing the future implementation to grow into a monolithic `app.py`. - The repository context mentions AI-assisted development, but this codebase currently exposes no runtime AI workflow. Reliability risk here comes from thin scaffolding, missing controls, and dependence on upstream `fedstylevalidator`, not from prompt logic inside this repo. ## Stability Risks - Direct UI-to-provider calls will make upstream FSV changes surface as user-visible failures with little isolation. - Upload handling, temp-file cleanup, corrupt `.docx` behavior, and optional hyperlink checks have no implemented safe failure path. - Missing tests and missing CI mean regressions can ship unnoticed. - Missing dependency pinning and missing startup config validation will make local and Hugging Face deployments non-reproducible. - Missing structured logs and request correlation will make production failures hard to diagnose. - Output downloads are planned, but there is no artifact validation path to prevent empty or malformed JSON, HTML, or DOCX exports. - Security basics are not yet implemented: file validation, filename sanitization, secret handling guidance, and dependency vulnerability scanning. ## Missing Infrastructure - A testable module boundary under `src/` - Typed request, config, and result contracts - Output normalization around FSV responses - Unified application error taxonomy - Retry, timeout, and recovery policy for failure-prone operations - `pytest` test suite with fixtures and end-to-end workflow coverage - Repository CI gates for lint, typing, tests, security, and startup checks - Structured logging, timing, and failure telemetry - Deterministic dependency management - Release readiness and rollback checklist ## Production Readiness Checklist - `ruff`, `mypy`, `pytest`, `bandit`, and `pip-audit` pass in CI - App startup validates configuration before serving requests - Critical workflow test passes: upload `.docx` -> run analysis -> render results -> generate JSON download - Oversize file, corrupt file, and provider failure paths are covered by automated tests - Structured logs include request ID, stage, duration, outcome, and error class - Runtime dependencies are pinned and vulnerability scan results are reviewed - Rollback procedure is documented for dependency and deployment regressions - Output schemas are enforced before rendering or download ## Simplicity Review - Keep root `app.py` thin. It should bootstrap Streamlit and delegate to package code. - Avoid passing raw dictionaries between layers. Normalize once and use typed models internally. - Avoid fallback chains that silently change behavior. Fail clearly on invalid config, invalid provider output, and unsupported files. - Keep one orchestration path for analysis and one normalization path for results. Do not duplicate result-shaping logic in UI code and download code. ## Implementation Roadmap ### P0 Critical Reliability Work #### Task: Establish a testable application boundary Problem: The planned architecture routes core behavior through `app.py`. That will create a fragile UI-centric module with poor separation of concerns and weak testability. Recommendation: Keep root `app.py` as a thin Streamlit bootstrap and move orchestration into a small package with explicit boundaries. Suggested Implementation: Create `src/fsv_streamlit/` with `ui.py` for Streamlit composition, `services/document_analysis.py` for workflow orchestration, `adapters/fsv_client.py` for all calls into `fedstylevalidator`, and `downloads.py` for export generation. Root `app.py` should only initialize app state and call the package entrypoint. Affected Files: - `app.py` - `src/fsv_streamlit/__init__.py` - `src/fsv_streamlit/ui.py` - `src/fsv_streamlit/services/document_analysis.py` - `src/fsv_streamlit/adapters/fsv_client.py` - `src/fsv_streamlit/downloads.py` #### Task: Add contract and schema validation Problem: The planned flow accepts user uploads, document types, visibility toggles, configuration values, and raw FSV results with no validation layer. Recommendation: Validate every external interface and normalize provider output before rendering or exporting it. Suggested Implementation: Introduce Pydantic models for `AppConfig`, `UploadRequest`, `AnalysisRequest`, `VisibilityOptions`, `Finding`, `AnalysisSummary`, `AnalysisResult`, and `DownloadArtifact`. Normalize raw FSV output into internal models before UI rendering. Reject invalid state early and explicitly. Affected Files: - `src/fsv_streamlit/config.py` - `src/fsv_streamlit/contracts.py` or `src/fsv_streamlit/contracts/` - `src/fsv_streamlit/adapters/fsv_client.py` - `src/fsv_streamlit/services/document_analysis.py` #### Task: Define a unified error taxonomy and failure policy Problem: Current docs mention `st.error()`, but there is no error classification, no structured failure policy, and no clear distinction between retryable and non-retryable problems. Recommendation: Create typed application errors and map them to user-safe messages, logs, and retry decisions. Suggested Implementation: Define `AppError`, `ConfigError`, `ValidationError`, `ProviderError`, `ParseError`, `RetryableError`, and `FileHandlingError`. Centralize error-to-UI translation and ensure temp-file cleanup occurs in one guarded workflow. Treat corrupt input as non-retryable and infrastructure/provider failures as conditionally retryable. Affected Files: - `src/fsv_streamlit/errors.py` - `src/fsv_streamlit/services/document_analysis.py` - `src/fsv_streamlit/adapters/fsv_client.py` - `src/fsv_streamlit/ui.py` #### Task: Build a reliability-focused test suite Problem: No automated tests exist for critical workflows or failure cases. Recommendation: Add unit, integration, and end-to-end coverage before feature growth. Suggested Implementation: Create `tests/unit/` for schema, config, and error handling; `tests/integration/` for adapter normalization and temp-file cleanup using mocked FSV responses; `tests/e2e/` for upload-to-results happy path, corrupt `.docx`, oversize file, and hyperlink-toggle workflows. Add golden JSON fixtures for stable output assertions. Affected Files: - `tests/unit/` - `tests/integration/` - `tests/e2e/` - `tests/fixtures/` - `pyproject.toml` #### Task: Add automated reliability gates in CI Problem: Formatting hooks on one machine are not a release gate. Broken code can still merge or deploy. Recommendation: Add repository-enforced CI for style, types, tests, security, and startup validation. Suggested Implementation: Create `.github/workflows/ci.yml` running `ruff check`, `ruff format --check`, `mypy`, `pytest`, `bandit -r src`, `pip-audit`, and a minimal startup smoke test for the Streamlit app. Fail the pipeline on any gate. Affected Files: - `.github/workflows/ci.yml` - `pyproject.toml` - `requirements.txt` - `requirements-dev.txt` or equivalent #### Task: Make dependencies and runtime configuration deterministic Problem: The repo depends on unpublished or changing packages and has no validated runtime configuration. Recommendation: Pin dependencies and validate configuration at startup instead of relying on implicit defaults. Suggested Implementation: Keep Hugging Face-compatible `requirements.txt`, add a pinned constraints file or lock file, and create startup config validation for upload limits, default document type, feature flags, and optional hyperlink checks. Fail fast on invalid config. Affected Files: - `requirements.txt` - `constraints.txt` or lock file - `.streamlit/config.toml` - `src/fsv_streamlit/config.py` - `README.md` #### Task: Add observability baseline Problem: There is no structured logging, request correlation, or duration tracking. Recommendation: Instrument the workflow so failures are diagnosable in local runs and Hugging Face logs. Suggested Implementation: Add structured logging with request IDs, safe document metadata, stage timings, result counts, and exception class names. Emit explicit events for upload accepted or rejected, FSV call started or completed or failed, and download generated. Affected Files: - `src/fsv_streamlit/observability.py` - `src/fsv_streamlit/services/document_analysis.py` - `src/fsv_streamlit/ui.py` ### P1 Stability Improvements #### Task: Add resilience controls around provider and file operations Problem: Optional hyperlink checking and synchronous provider calls may be slow or fail unpredictably. Recommendation: Constrain risky operations with timeouts, bounded retries, and explicit degradation behavior. Suggested Implementation: Implement per-operation timeout settings, exponential backoff only for retryable failures, and a disable path for hyperlink checks when repeated network or provider failures occur. Keep the default path simple and explicit rather than silently falling back. Affected Files: - `src/fsv_streamlit/services/document_analysis.py` - `src/fsv_streamlit/adapters/fsv_client.py` - `src/fsv_streamlit/config.py` #### Task: Add secure file and artifact handling Problem: User-supplied DOCX files and generated downloads create parsing and artifact integrity risks. Recommendation: Validate file type, filename handling, temp-file lifecycle, and generated artifact integrity. Suggested Implementation: Accept only `.docx` with MIME or content sanity checks, sanitize output filenames, isolate temp directories, verify generated JSON or HTML or DOCX artifacts exist and are non-empty before download, and never log document contents. Affected Files: - `src/fsv_streamlit/file_io.py` - `src/fsv_streamlit/downloads.py` - `src/fsv_streamlit/services/document_analysis.py` - `tests/integration/` #### Task: Add deployment and release readiness checks Problem: Hugging Face Spaces is the production target, but there is no release checklist or smoke-test path. Recommendation: Create a repeatable release gate for startup, configuration, and core workflow health. Suggested Implementation: Add `docs/release-checklist.md` with pre-merge and pre-deploy checks, plus a smoke test that validates app startup, sample upload processing, and artifact download generation in a clean environment. Document rollback steps for dependency and deployment regressions. Affected Files: - `docs/release-checklist.md` - `.github/workflows/ci.yml` - `README.md` - `tests/e2e/` #### Task: Add static typing and interface discipline Problem: AI-generated code commonly drifts into weakly typed helper functions and unstructured dictionary passing. Recommendation: Use strict typing at module boundaries and stop passing raw dictionaries through the app. Suggested Implementation: Enable `mypy` for `src/`, add typed interfaces around the FSV adapter, and require internal functions to accept and return models instead of raw provider dictionaries. Affected Files: - `pyproject.toml` - `mypy.ini` or `pyproject.toml` - `src/fsv_streamlit/**/*.py` ### P2 Long-term Hardening #### Task: Add compatibility and regression testing against FSV versions Problem: This repo’s reliability depends heavily on upstream `fedstylevalidator` behavior and response shape. Recommendation: Create contract tests that detect upstream schema or behavioral drift before deploy. Suggested Implementation: Pin a supported FSV version range, add compatibility tests against the current supported version and the next candidate version, and snapshot normalized outputs for representative documents. Affected Files: - `tests/contracts/` - `requirements.txt` - `README.md` #### Task: Add lightweight metrics and operational dashboards Problem: Logs alone will not show latency regressions or failure trends over time. Recommendation: Track a small operational metric set and document target thresholds. Suggested Implementation: Record analysis latency, upload rejection counts, provider failure counts, and download generation failures. Emit metrics through logs first and add a metrics sink later if the hosting platform supports it. Affected Files: - `src/fsv_streamlit/observability.py` - `docs/operations.md` #### Task: Simplify and document control flow Problem: The future app can accumulate hidden conditional logic around toggles, grouping, downloads, and provider behavior, which increases reliability risk. Recommendation: Prefer one orchestration path with explicit stages and documented invariants. Suggested Implementation: Write `docs/architecture.md` describing the request lifecycle, config sources, contracts, failure classes, and non-goals. Keep one analysis path and one normalization path. Avoid fallback chains that produce partially validated states. Affected Files: - `docs/architecture.md` - `src/fsv_streamlit/services/document_analysis.py` - `app.py`