## 1. Dependency and lockfile - [x] 1.1 Add `jinja2>=3.1` to the `dependencies` list in `apps/device-host-agent/pyproject.toml` - [x] 1.2 Run `uv lock` (or `uv lock --package device-host-agent`) and confirm `jinja2` plus its sole transitive runtime dependency `markupsafe` resolve; commit the updated `uv.lock` - [x] 1.3 Run `uv sync --locked --all-packages` and confirm no package fails to install ## 2. Capture pre-migration reference - [x] 2.1 From a clean working copy of the current `host_agent/web/app.py`, render each of the five pages (login, dashboard, devices, account, history) in-process with a representative context (mock `SessionState`, mock `HostIdentityState`, two sample devices, one history entry) and save the HTML to `apps/device-host-agent/tests/host_agent/web/__baseline__/` as `.html` (one file per page). The dashboard reference must include the rendered inline `` (device name, device driver_type, connection_info JSON string, history summary) and asserts the substring `` does not appear in the output while `<script>alert(1)</script>` does - [x] 6.5 Add a byte-identity test that loads the dashboard template, renders it with a representative context, and asserts the inline `` (and a valid driver type/connection info); confirm the device appears in the list with the script visible as text rather than executing, then remove it - [ ] 8.4 Visit `/account`, change the password (current → new → confirm) end-to-end, log out, and log back in with the new password - [ ] 8.5 Visit `/history` and confirm recent entries render - [ ] 8.6 Compare each page's visual layout to the pre-change version and confirm no styling regression (the `_CSS` content must be byte-identical inside `base.html`'s `