Spaces:
Running
Running
| # BugLens Plan 03 - Architecture, Flows, And Product Shape | |
| Research date: 2026-06-09 | |
| Purpose: define the system shape before implementation so the app feels engineered, not improvised. | |
| ## Product Flow | |
| ```mermaid | |
| flowchart TD | |
| A["Tester uploads screenshot"] --> B["Tester adds one-line note"] | |
| B --> C["BugLens reads visible UI facts"] | |
| C --> D["BugLens structures validated bug artifact"] | |
| D --> E["Bug report card"] | |
| D --> F["Missing info card"] | |
| D --> G["Regression tests card"] | |
| D --> H["Edge cases card"] | |
| E --> I["Export Jira markdown"] | |
| G --> J["Export CSV"] | |
| E --> K["Export GitHub issue"] | |
| ``` | |
| ## Primary Technical Architecture | |
| This is the recommended plan if Modal works by the Thursday gate. | |
| ```mermaid | |
| flowchart LR | |
| U["User in browser"] --> S["Hugging Face Gradio Space"] | |
| S --> V["Validate image and note"] | |
| V --> M["Modal GPU endpoint"] | |
| M --> MV["MiniCPM-V 4.6"] | |
| MV --> O["Factual observation"] | |
| O --> M2["Structuring call"] | |
| M2 --> J["Strict JSON"] | |
| J --> P["Pydantic validation"] | |
| P --> R["Render cards and exports"] | |
| R --> U | |
| ``` | |
| Why this architecture: | |
| - Meets the requirement that the app is a Gradio Space. | |
| - Keeps the public app simple. | |
| - Uses Modal enough to honestly qualify as Modal-powered. | |
| - Lets the GPU model stay outside the frontend runtime. | |
| - Reduces Gradio sticky-session risk because the Space remains the user-facing app. | |
| ## Fallback Technical Architecture | |
| Use this if Modal is unstable. | |
| ```mermaid | |
| flowchart LR | |
| U["User in browser"] --> S["Hugging Face Gradio Space"] | |
| S --> Z["ZeroGPU decorated function"] | |
| Z --> MV["MiniCPM-V 4.6"] | |
| MV --> O["Observation and structured JSON"] | |
| O --> P["Pydantic validation"] | |
| P --> R["Four cards and exports"] | |
| R --> U | |
| ``` | |
| Important ZeroGPU facts: | |
| - Source: https://huggingface.co/docs/hub/spaces-zerogpu | |
| - Use `@spaces.GPU` around GPU-dependent functions. | |
| - ZeroGPU is compatible with Gradio SDK only. | |
| - Personal hosting requires PRO; organization hosting requires Team/Enterprise. | |
| - Daily quotas and queue priority matter. | |
| ## Optional Local-First Architecture | |
| Only build this after the core submission works. | |
| ```mermaid | |
| flowchart LR | |
| U["User"] --> L["Local BugLens runtime"] | |
| L --> LC["llama.cpp or Ollama"] | |
| LC --> G["MiniCPM-V 4.6 GGUF"] | |
| G --> O["Observation"] | |
| O --> P["Pydantic validation"] | |
| P --> R["Cards and exports"] | |
| ``` | |
| Why this matters: | |
| - Needed for a credible Off the Grid claim. | |
| - Needed for a credible Llama Champion claim if using llama.cpp. | |
| - Not needed for the core win. | |
| - Risky to prioritize before the Space is done. | |
| ## Two-Call Model Pipeline | |
| ```mermaid | |
| sequenceDiagram | |
| participant UI as Gradio UI | |
| participant V as Vision Call | |
| participant S as Structuring Call | |
| participant P as Pydantic | |
| participant R as Renderer | |
| UI->>V: screenshot + tester note + factual prompt | |
| V-->>UI: visible UI observation only | |
| UI->>S: observation + tester note + JSON schema prompt | |
| S-->>UI: JSON candidate | |
| UI->>P: validate JSON | |
| alt valid | |
| P-->>R: BugReport object | |
| R-->>UI: cards, Jira markdown, GitHub markdown, CSV | |
| else invalid | |
| P-->>S: retry once with strict JSON reminder | |
| S-->>P: second JSON candidate | |
| P-->>UI: valid output or graceful error card | |
| end | |
| ``` | |
| Why two calls: | |
| - Call 1 is perception: "What is visible?" | |
| - Call 2 is product reasoning: "How should a bug ticket be shaped?" | |
| - Separating the calls improves honesty, makes debugging easier, and gives you a clean demo explanation. | |
| ## Data Contract | |
| Use one validated object as the app contract: | |
| ```text | |
| BugReport | |
| - title: string | |
| - severity: enum[P1, P2, P3] | |
| - component: string | |
| - steps: list[string] | |
| - expected: string | |
| - actual: string | |
| - missing_info: list[string] | |
| - regression_tests: list[RegressionTest] | |
| - edge_cases: list[string] | |
| RegressionTest | |
| - id: string | |
| - desc: string | |
| ``` | |
| Do not allow UI code, export code, and model code to each invent their own shape. Everything should pass through this contract. | |
| ## Module Layout | |
| ```text | |
| buglens/ | |
| app.py | |
| requirements.txt | |
| README.md | |
| buglens/ | |
| __init__.py | |
| schema.py | |
| prompts.py | |
| vision.py | |
| structure.py | |
| render.py | |
| examples.py | |
| modal_app.py | |
| theme.py | |
| examples/ | |
| broken_payment.png | |
| login_error.png | |
| empty_dashboard.png | |
| mobile_overflow.png | |
| tests/ | |
| test_schema.py | |
| test_render.py | |
| test_missing_info.py | |
| ``` | |
| Responsibilities: | |
| | File | Responsibility | | |
| |---|---| | |
| | `app.py` | Build UI and wire events only | | |
| | `schema.py` | Pydantic contract | | |
| | `prompts.py` | Versioned prompts | | |
| | `vision.py` | Screenshot to observation | | |
| | `structure.py` | Observation to validated report | | |
| | `render.py` | Jira, GitHub, CSV, card formatting | | |
| | `modal_app.py` | Modal GPU endpoint | | |
| | `theme.py` | UI theme and Off-Brand styling | | |
| | `tests/` | Contract and rendering tests | | |
| ## UI Layout | |
| ```mermaid | |
| flowchart TD | |
| A["Header: BugLens"] --> B["Left panel: upload screenshot, note, examples"] | |
| A --> C["Right panel: Generate button and status"] | |
| C --> D["Bug Report card"] | |
| C --> E["Missing Info card"] | |
| C --> F["Regression Tests card"] | |
| C --> G["Edge Cases card"] | |
| D --> H["Copy Jira"] | |
| D --> I["Copy GitHub Issue"] | |
| F --> J["Download CSV"] | |
| ``` | |
| Design requirements: | |
| - The first viewport should be the actual tool, not a landing page. | |
| - The four cards are the product. | |
| - Missing Info must be visually prominent. | |
| - Export buttons should be obvious and useful. | |
| - Use example screenshots so judges can try it immediately. | |
| - Avoid huge hero copy. This is an operational QA tool. | |
| ## Reliability Requirements | |
| Must handle: | |
| - No screenshot uploaded. | |
| - Huge screenshot. | |
| - Unsupported file type. | |
| - Empty user note. | |
| - Model timeout. | |
| - Invalid JSON. | |
| - Missing fields. | |
| - Model guesses context it should not guess. | |
| Graceful states: | |
| - "I need a screenshot to inspect the UI." | |
| - "The model returned invalid JSON. Try again or use the observation text." | |
| - "I cannot determine browser, device, user role, or environment from the screenshot." | |
| ## Performance Targets | |
| Acceptable for hackathon: | |
| - First cold generation: under 60 seconds. | |
| - Warm generation: under 20 seconds. | |
| - UI response after validation: immediate. | |
| - Exports: instant. | |
| If slow: | |
| - Use MiniCPM `downsample_mode="16x"` first. | |
| - Switch to `4x` only for tiny text/OCR-heavy screenshots. | |
| - Limit max tokens for observation and structure calls. | |
| - Use short example screenshots. | |