# Portable demo and sample review `uv run vdr build-demo --output runs/demo/my-demo` packages the current offline retrieval artifacts and five existing sample cache entries. No API key or network is needed to build when the artifacts are already local. Use `--model` if the samples were cached using a different generation model. Missing/invalid cache entries stop the build without making provider requests. An existing output directory is never overwritten; failed builds remove their partial output. The output includes app source, `pyproject.toml`/`uv.lock`, assets, documentation, pinned model snapshots, both indexes, all page images, supplied markdown, dataset provenance, source URLs/licenses and exactly five cached example responses. `bundle.json` lists file sizes and SHA-256 hashes; it does not hash itself. Personal query history, keys, usage counters, raw benchmark queries/reference answers/qrels and Hugging Face download caches are excluded. From the output directory, run `uv sync --locked`, configure `.env` from `.env.example`, then `uv run python app.py`. Installing dependencies may require internet; retrieval does not. The current app requires a key to initialize even for cached questions. The five exact sample questions use no provider quota with the matching model/prompt/indexes. Other questions use the normal provider and quota flow. Evaluation/download/indexing commands still need the original data directory; the bundle is intended for search, answers and the app. The first bundle keeps original RGB PNG bytes. Reducing their resolution would invalidate existing image-hash cache entries and change the evidence supplied to generation. Compression and deliberate cache migration are deferred; no answer has been relabeled as generated from a different image. Model weights and page images make the bundle approximately 1.82 GB. CPU query encoding is unchanged. ## Verification on 2026-10-21 - 33 automated tests and Ruff pass. Tests include cache-only misses/invalid citations, path traversal/symlinks, existing-output protection and portable retrieval/report export without raw benchmark tables. - A real bundle contains 1,110 pages, 2,283 tracked files and five sample entries. Every file hash was verified before runtime checks. File count grows when new documentation is included; use the generated manifest as the source of truth. - From the bundle's own working directory and source, all five hybrid questions hit cache with raw-table loading and generation replaced by failing stubs. - The Gradio callback returned cited evidence and ZIP/JSON downloads. This check uses the callback, not a new browser automation run. Earlier browser checks remain documented in README. Local verification evidence is kept under ignored `runs/`; no API requests were made for building, sample review or verification. ## Manual review of the five existing cached answers This is a focused smoke review of main claims against retrieved images, not an answer-quality benchmark or a complete check of every cited page. No benchmark reference answers or qrels were used, and the cached responses were not edited. | Sample topic | Image checked (corpus ID) | Observation | | --- | --- | --- | | Working age | 328 | The definition supports ages 20–64. | | Cross-border mobility versus posting | 468, 470 | The main definitions, temporary posting and PD A1/prior-declaration tracking match the images. | | PD A1 issuer and yearly change | 471 | **Incorrect numeric attribution:** Germany is the leading issuer, with over 2 million and an increase of 408,000 (+25%). The answer then attaches Poland's 850,000 total to Germany, contradicting its own earlier total. | | Three types of posting | 961 | The image supports service contracts, intra-group posting and temporary agency posting. | | Telework opportunities | 882 | The image supports heterogeneous teleworkability, mostly below average, especially for occupations with labour shortages. | The table above records the original prompt v1 responses, including the observed PD A1 generation failure. Cache/citation/schema validation checks structure and membership, not factual support. Prompt v2 adds explicit checks for entity, year, unit and total versus change, and invalidates the previous answer cache. All five samples were regenerated using five provider attempts on 2026-10-21. The refreshed PD A1 response cites page 471 and states Germany issued over 2 million, up 408,000 (+25%); it no longer attaches Poland’s total to Germany. The other refreshed answers retain the supported main claims; the mobility comparison additionally states 1.8 million cross-border workers and 5.5 million PDs A1 (+19.5%), supported by pages 468 and 470. This focused check does not establish general answer quality. ## Public deployment verified on 2026-10-21 The [public Space](https://huggingface.co/spaces/tungpth/visual-doc-rag) and [direct app](https://tungpth-visual-doc-rag.hf.space) are live on free ZeroGPU. The Space bundle is about 779 MB; it downloads pinned model weights at startup to stay within the observed 1 GB repository limit. The full offline bundle still includes weights. Setup and host quota limits are documented in [HOSTING.md](HOSTING.md). A real Chromium session verified all five sample clicks as cache hits, cited images and ZIP/JSON downloads. Two uncached questions exercised ZeroGPU encoding, CPU ranking and Gemini: a vague question referring only to “the 2024 report” retrieved insufficient evidence and received an abstention; an explicit question about working-age EU citizens in the 2024 labour mobility report returned 20–64, citing corpus page 328. The vague question’s CPU ranking also lacked the age-definition page, so this is a retrieval/query-specificity limitation rather than a provider submission failure. This remains a smoke check, not systematic evaluation. No new-question answers or runtime reports were uploaded to the repo. The README GIF was captured from the live public app using the corrected cached PD A1 sample. Its frames show the question, cached answer and source page 471; they are real browser screenshots, not mockups. Local browser logs, screenshots, GIF frames and provider-review records remain under ignored `runs/qa/`. 35 automated tests and Ruff pass with the hosting-compatible dependency pins.