# 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
  <HermesOpsPanel>, 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.
