# Delegation Brief — Dashboard CI + E2E Hardening > Self-contained task brief for a delegated agent (Hermes `delegate_task`, a fresh > Claude Code / Devin session, etc.). Generated 2026-05-30. Execute the whole thing > end-to-end and report per the Final Report section. > > Related: `docs/hermes_dashboard_v2_roadmap.md` (Phase 5), `dashboard/REVIEW_ACTIONS.md` (#2, #11). --- ROLE: Senior fullstack + DevOps engineer. OBJECTIVE: Make the ByteLyst DevOps Dashboard's end-to-end (Playwright) test suite complete and GREEN inside the self-hosted Gitea CI. Fixing the broken CI workflow is a prerequisite and is in scope. REPO & STACK (start by reading, don't assume): - Repo: /opt/bytelyst/learning_ai_devops_tools (GitHub remote: bytelyst-devops-tools) - App: dashboard/ pnpm workspace — backend/ (Fastify 5, @bytelyst/devops-backend, :4004) and web/ (Next.js 16, @bytelyst/devops-web, :3000 / container 3049). - Tooling: Node 22+, pnpm 10.6.5. Vitest = unit, Playwright = E2E. - Read first: docs/hermes_dashboard_v2_roadmap.md (Phase 5), dashboard/REVIEW_ACTIONS.md (#2 lint, #11 E2E), and dashboard/.gitea/workflows/ci.yml. CONTEXT YOU NEED: - CI runs on a LOCAL self-hosted Gitea act_runner (/opt/bytelyst/.act_runner). Keep it local — do NOT move CI to GitHub-hosted runners. - ci.yml is currently broken: every step `cd`s into the non-existent path /opt/bytelyst/bytelyst-devops-tools/dashboard and does `git reset --hard origin/main` on the live host checkout. The real path is .../learning_ai_devops_tools/dashboard. - Existing E2E specs: web/e2e/dashboard.spec.ts and web/e2e/hermes.spec.ts. `pnpm test:e2e` is defined but not reliably wired (no started stack). - Hermes Mission Control routes to cover: /hermes, /hermes/tasks, /hermes/tasks/[id] (use a real seed id from web/src/lib/hermes), /hermes/products, /hermes/history, /hermes/agents, /hermes/settings. Plus / (dashboard) and /login. - IMPORTANT determinism note: the 6 Mission Control panes render from client-side seed data (web/src/lib/hermes) and need NO backend. BUT the /hermes overview also mounts , which calls api.getHermesOps() → backend (which shells out to systemctl/git/ps on the VM and WON'T work in CI). Make E2E deterministic by intercepting that API call with Playwright page.route() and returning a fixture snapshot. Do the same for any other live backend call. - Auth: app may redirect to /login (platform-service). Use a Playwright global-setup that authenticates once and reuses storageState, OR a documented test auth bypass. Do not hardcode real credentials — read from env / .env.example placeholders. TASKS: 1. Fix dashboard/.gitea/workflows/ci.yml: - Replace host-path `cd` + `git reset --hard` with checkout into ${{ gitea.workspace }} (actions/checkout) + `working-directory: dashboard` on steps. CI must NOT mutate the live host checkout. - Use `pnpm install:gitea` (local Gitea registry mode) so CI is self-contained instead of depending on a sibling learning_ai_common_plat checkout. - Keep the existing build/typecheck/test/secret-scan/docker steps working. - Fix the same stale path in DEPLOYMENT.md and scripts/deploy-hotcopy.sh. 2. Make `lint` real (it's currently `echo`): `next lint` for web, minimal ESLint + @typescript-eslint for backend. `pnpm lint` must fail on bad code. 3. Complete the Playwright E2E suite so it loads every route above, asserts key content renders (headings, the ops-panel "Healthy instances X/2" card, the task table, filters), and asserts ZERO console errors per page. Add at least one mobile-width run. 4. Wire E2E into CI with a started stack: prefer Playwright's `webServer` config to build + start web (and backend if needed) before tests, so the Gitea "E2E tests" step is self-contained. Document any required env in .env.example, not real secrets. GUARDRAILS: - Private-only project: do not add any public route/listener; do not expose anything. - Do not commit secrets, tokens, OAuth files, state.db, or SQLite WAL/SHM. - Keep changes minimal and reuse existing conventions; do not rewrite the app. VERIFY (all must pass from dashboard/): - pnpm install:gitea (or install:common-plat for local dev) - pnpm secret-scan - pnpm --filter @bytelyst/devops-backend typecheck && build && test:run - pnpm --filter @bytelyst/devops-web typecheck && build && test:run - pnpm lint (now real, must pass) - pnpm --filter @bytelyst/devops-web test:e2e (must pass, no console errors) GIT FLOW: - Work on branch `ci/e2e-hardening`. Commit incrementally with clear messages. - Push the branch and trigger one Gitea CI run; confirm it goes GREEN end-to-end (build → test → lint → E2E → docker). Only then open a PR to main. DEFINITION OF DONE: - Gitea CI is green on the corrected workflow, lint is real, and the E2E step runs the full suite (all 7 Hermes routes + dashboard + login) deterministically with no console errors, including a mobile-width pass. FINAL REPORT: summarize files changed, how E2E is started in CI, what was mocked and why, the green CI run link/id, and any gaps left.