// roadmap

Roadmap

The working backlog after Milestone 1 — grouped by epic, kept in sync by hand as work lands.

The forward plan after Milestone 1 (the manual-run core: Home → Package Picker → Runner → Run Summary, with on-fail evidence). Milestone 1 is complete on main; its build order is recorded in BUILD-ORDER-AND-MILESTONE-1.md.

This file is the working backlog. It is grouped by epic (a theme) with its issues beneath. Each issue carries a phase and a rough effort. It is kept in sync by hand as work lands; when the issue board is stood up, each epic becomes a parent and each issue a child, one-to-one by title.

Status: ☐ not started · ◐ in progress · ☑ done Effort: S (hours) · M (a day or two) · L (several days) · XL (multi-week)

Phases

PhaseThemeFocus
P0Foundations & honestyClose the Milestone-1 gaps and put a baseline security floor under the local-admin auth seam.
P1Multi-userReal authentication, roles, and access control — more than one bootstrap admin.
P2Works with your stackIn-product authoring, agent runs, more tracker integrations, and evidence at scale.
P3Launch & operabilityRelease, deploy, quality gates, docs, and sign-off.

Recommended next (in order)

  1. Capture screenshots + screen recording in the Runner client (P0) — the remaining headline gap. The console/network/env capture around it now records real data; the recording/screenshot path is browser-only and needs a manual verification pass.
  2. User & role management + RBAC (P1) — unlock real multi-user beyond the bootstrap admin (session lifecycle is now hardened; RBAC has little to gate until this exists).
  3. Audit persistence + admin view (P2) — complete the audit trail: privileged actions now emit structured events to stdout; persist them to the DB and surface an admin-viewable log.
  4. OIDC / forwarded-header auth (P1) — needs an IdP + a documented trust model; a founder decision, not an overnight merge.
  5. Playwright e2e in CI (P3) — lock the core flows before building on them.

Epic — Evidence capture, storage & redaction

End-to-end evidence: capture real artefacts in the Runner client, store them durably, and redact sensitive content before it leaves the box.

  • Capture screenshots + screen recording in the Runner clientP0 · L — the Runner has the affordances but records placeholder/derived evidence; wire real browser capture through the capture-buffer route into the bundle (respecting QA_MAX_RECORDING_MB). (Shipped: Runner "Shot"/"Record" controls capture the screen via getDisplayMedia/MediaRecorder; on a fail the media is merged into the server-promoted evidence bundle through the /evidence route (mergeEvidenceMedia), respecting the recording cap on both client and server. Pure helpers (src/lib/qa/capture/*) are unit-tested; the browser hook (useScreenCapture.ts) is browser-only and CI-unverifiable — needs a manual verification pass. Pixel-level redaction of the media stays the separate P2 item below.)
  • Capture real HAR / console / env (stop server-reconstructing)P0 · M — capture HAR, console and env client-side during the run so they match what the tester actually saw, instead of reconstructing them server-side. (Console + network cues and the real browser/os/viewport environment now land client-side; a structured HAR export is what remains.)
  • S3-compatible evidence storage backendP2 · M — add a pluggable object-store backend behind the evidence seam (fs | s3) with signed reads; filesystem stays the zero-dep default.
  • Pixel-level evidence redactionP2 · L — blur/blackout regions baked into the stored artefact before it is persisted or shared.
  • Per-deck redaction rules + settings UIP2 · M — let a deck declare redaction rules so capture auto-redacts, plus a settings surface to manage them.
  • Evidence retention + garbage collectionP2 · M — configurable retention window/quota + a GC job with dry-run; never prunes evidence for an open run without opt-in.

Epic — Runner UX completion

Close the remaining Runner interaction gaps so a full manual pass is smooth end to end.

  • Register the ⌘K command-palette commandsP0 · M — the palette is the primary nav (no sidebar) but the registry is sparse; register the real nav + actions (start run, open package, jump to run/summary, file issue, logout).
  • "Re-run the N fails" from the run SummaryP0 · M — one-click re-run scoped to just the failed cases, creating a new run seeded from those fails and linked back.
  • Wire the logout flowP0 · SdestroySession() exists but is never called; add a logout action (destroy session + clear cookie) surfaced in the top bar and ⌘K.

Epic — Authentication & sessions (SSO)

Move beyond the single bootstrap admin: real sign-in options and a hardened session lifecycle.

  • OIDC authenticationP1 · L — OIDC (auth-code + PKCE) alongside local-admin, mapping identities to users/roles; local-admin stays available for bootstrap/offline.
  • Trusted X-Forwarded-User (reverse-proxy) authP1 · S — opt-in support for an authenticating reverse proxy, off by default, with a trusted-proxy allowlist and a documented threat model.
  • Session hardening: rotation, revocation, reaperP1 · M — rotate session id on privilege change, support server-side revocation (one/all), and expire stale sessions. (Idle timeout + absolute cap, revokeAllUserSessions, and a reaper shipped. Password change already rotates the session; id-rotation on role change lands with role management, since no role-change path exists yet.)
  • Central fail-closed auth middlewareP1 · S — a central boundary so a new route is protected by default and must explicitly opt out to be public.

Epic — Users, roles & access control

Multi-user Teasynaer: manage people, enforce roles, and scope what each can see.

  • Scope the capture-buffer route to run ownershipP0 · S — the capture-buffer route accepts uploads without verifying run ownership; scope it server-side (a tenant-isolation gap once multi-user lands).
  • User & role management (invite / CRUD / password reset)P1 · L — invite/accept, user CRUD + role assignment, deactivation, and self-serve/admin password reset.
  • Enforce admin|member RBACP1 · M — enforce the role enum consistently across routes/actions server-side; UI hides what the role can't do; matrix documented + tested.
  • Per-run / per-result evidence ACL + team scopingP1 · L — scope runs/results/evidence to a team/owner and enforce it on read paths and list views.

Epic — Issue-tracker integrations

Make the IssueTracker seam production-grade and pluggable.

  • Tracker credential storage + admin config UI + SSRF guardP1 · M — encrypted at-rest credentials, an admin config UI, and an SSRF guard on the outbound file-issue request (block internal ranges/metadata endpoints). (SSRF guard landed — blocks loopback/private/reserved + non-http(s), with a self-hosted opt-out; encrypted credential storage + admin UI remain.)
  • More tracker adapters: GitHub / GitLab / Jira / webhookP2 · L — implement adapters behind the existing seam; GitHub Issues first (highest demand), then GitLab, Jira, and a generic webhook. (All shipped: huly · github · gitlab · jira · webhook behind the hardened seam. github/gitlab/jira/webhook are mocked-tested like the existing Huly adapter; the Jira ADF/Basic-auth path wants one smoke test against a real instance.)
  • Harden the IssueTracker seamP2 · S — typed adapter interface + error taxonomy, timeouts + bounded retries, secrets never logged, clean no-op when unconfigured. (Shared timeout + bounded-retry policy across all adapters; typed interface + generic error messages that never leak the token. Structured error taxonomy is a light follow-up.)

Epic — Authoring: Case Editor & Scenarios

Author decks in-product rather than by seed script.

  • Case Editor (build-order step 5)P2 · XL — CRUD for packages/cases/steps in the brand UI with validation and versioning-friendly persistence to the owned schema.
  • Recording → Scenario (build-order step 6)P2 · L — turn a captured interaction recording into an editable, re-runnable scenario draft that round-trips with the Case Editor.
  • Seed 3 more decks: Checkout, Onboarding, SearchP2 · S — ship more example decks beyond Auth so evaluators see breadth, in the same seed format.

Epic — Agent runs & targeting engine

Drive a case against a live target automatically.

  • Agent-run / ⌖-target engine (build-order step 7)P2 · XL — point a case at a live target, execute steps, auto-capture results and evidence, and reconcile against the manual pass/fail/skip verdict model with human override.

Epic — Baseline security hardening

The pre-launch security floor for the local-admin auth seam.

  • Login rate-limit / lockout + first-login password changeP0 · M — per-account/IP rate-limiting + lockout/backoff, and force a change of the bootstrap password on first login; lockouts auditable.
  • CSRF protectionP0 · M — CSRF defence (token or SameSite + origin checks) on all state-changing routes; regression test for a forged cross-site POST.
  • Wire or remove the inert session secretP0 · STEASYNAER_SESSION_SECRET is read but inert (sessions are DB-backed); either sign/encrypt the cookie with it (and fail closed without it in prod) or remove it so config doesn't imply protection that isn't there.
  • Audit loggingP2 · M — structured audit events for privileged actions (login/logout, role changes, tracker config, evidence delete, issue filed) with actor + timestamp, retained and admin-viewable. (Structured events now emit to stdout — login success/failure/lockout, logout, password change, issue filed — with actor + timestamp. DB persistence + an in-app admin view remain.)

Epic — Release, deploy & operability

Ship it and run it.

  • DB + evidence backups / restoreP3 · M — scheduled DB dump + evidence snapshot and a tested restore runbook, verified end-to-end at least once. (Shipped: scripts/backup.sh + scripts/restore.sh snapshot/restore Postgres (pg_dump -Fc) and the evidence store as a consistent pair — evidence first, then DB — for compose or host. docs/runbooks/backup-restore.md documents the procedure + a step-by-step restore drill. The end-to-end drill itself needs a live PG16 and is not yet recorded — the runbook has the drill table awaiting its first run.)
  • Monitoring / alerting / SLOs + deeper healthP3 · M — readiness/liveness that reflect the DB + evidence store, metrics, basic alerts, and stated SLOs. (Deeper health shipped: /api/readyz (DB SELECT 1 + evidence-store writable) and /api/livez (process-up), built on a pure, unit-tested aggregateHealth core; /api/health now runs the same combined check. Metrics + alerting + stated SLOs remain.)
  • Supply-chain hardening: SBOM + signed imagesP3 · M — SBOM per release, signed/verifiable container images, and dependency pinning/verification (building on the osv-scanner/gitleaks CI). (SBOM half shipped: the release workflow runs syft to emit an SPDX SBOM per tag. Image signing (cosign) is wired but gated — it needs a keypair provisioned, so it's flagged, not active.)
  • Release & versioning (CHANGELOG + tags + image publish)P3 · S — semver tags, a CHANGELOG, and a published versioned image per release with a documented upgrade path. (Shipped: CHANGELOG.md (Keep a Changelog), docs/RELEASING.md (semver-for-a-self-hosted-image policy, release ritual, forward-only-migration upgrade path), and a v*-tag-triggered .forgejo/workflows/release.yml that builds the image + generates the SBOM. The image-publish step is registry-secret-gated and untested until the first real tag — flagged in RELEASING.md.)
  • teasynaer.dev deploy (DNS/TLS + staging/prod)P3 · M — stand up the public reference site with DNS + TLS and a staging + prod deployment, GitOps-consistent, documented as a self-host reference.

Epic — Quality, docs & launch readiness

The confidence to launch.

  • Playwright e2e in CIP3 · L — end-to-end tests for the core flows (login, run a pass, record a fail, view summary) running in CI against an ephemeral DB. (Shipped: e2e/core-flow.spec.ts walks login → first-login password change → start the seeded Auth deck → record a pass + a fail → view the summary, verified green locally against a real app + fresh Postgres. playwright.config.ts boots the app itself; .forgejo/workflows/e2e.yml runs it against an ephemeral Postgres service (kept off the required PR gates so the heavier browser job never blocks a merge). The first push-to-main runner execution failed (runner-side plumbing — service reachability / browser deps — not the spec), so the workflow is currently workflow_dispatch-only until a dispatched run's log is reviewed and the runner is tuned; then re-enable the main trigger.)
  • Reconcile README/status + launch docsP3 · M — bring the README/status claims back in line with reality and write an honest self-host quickstart (what works, what's next). (README rewritten: status is now "pre-launch v0.1.0, self-hostable via Docker"; the quickstart is real; the screen-capture claim is corrected (browser-gated, manual + on-fail attach, not auto-from-case-start); the full five-adapter tracker set, a Security section, and an Operations section (health/backup/release) are added.)
  • Governance & OSS compliance sign-off (NOTICE + attributions)P3 · S — complete the release governance trail: asset/risk sign-off, OSS-release approval, and a NOTICE file with third-party attributions. (NOTICE added: provenance per ADR 0001 §5, the three bundled OFL-1.1 font families with copyrights + full license text in licenses/OFL-1.1.txt, and direct-dependency licenses (verified against the installed packages). The asset/risk sign-off + OSS-release approval are a founder/governance step, tracked in the ISMS, not a code change.)
  • Dogfood a real regression passP3 · M — run a real manual regression pass against a live application using Teasynaer, capture evidence, file a real issue via an adapter, and feed the friction back into this backlog.