diff --git a/core/auth/ui/.gitignore b/core/auth/ui/.gitignore
index cbfcd69..984983f 100644
--- a/core/auth/ui/.gitignore
+++ b/core/auth/ui/.gitignore
@@ -1,3 +1,5 @@
 server
 server_arm64
 server_amd64
+e2e/cache
+e2e/artifacts
diff --git a/core/auth/ui/Makefile b/core/auth/ui/Makefile
index cb29df7..da8b9c7 100644
--- a/core/auth/ui/Makefile
+++ b/core/auth/ui/Makefile
@@ -1,13 +1,28 @@
 repo_name ?= giolekva
 podman ?= docker
 docker_flags=--provenance=false --sbom=false
+
+.PHONY: test test-e2e test-e2e-offline clean-e2e-artifacts
 ifeq ($(podman), podman)
-manifest_dest=docker://docker.io/$(repo_name)/pcloud-installer:latest
+manifest_dest=docker://docker.io/$(repo_name)/auth-ui:latest
 endif
 
 clean:
 	rm -f server server_*
 
+test:
+	go test ./...
+	go vet ./...
+
+test-e2e:
+	go test -tags=e2e -count=1 -timeout=10m -v ./e2e
+
+test-e2e-offline:
+	AUTH_UI_E2E_OFFLINE=1 go test -tags=e2e -count=1 -timeout=10m -v ./e2e
+
+clean-e2e-artifacts:
+	rm -rf -- e2e/artifacts
+
 build: clean
 	go build -o server *.go
 
diff --git a/core/auth/ui/e2e/README.md b/core/auth/ui/e2e/README.md
new file mode 100644
index 0000000..5e2a8ac
--- /dev/null
+++ b/core/auth/ui/e2e/README.md
@@ -0,0 +1,174 @@
+# auth-ui native end-to-end tests
+
+This directory contains the opt-in, serial browser suite for `auth-ui`. It builds the current application, starts native Ory processes with in-memory SQLite databases, and drives the existing UI with Playwright-managed headless Chromium. Docker and PostgreSQL are not prerequisites.
+
+## Pinned runtime
+
+The harness accepts no `latest` or system-browser fallback:
+
+- Go **1.22 or newer** (the module directive is exactly `go 1.22`)
+- Kratos **v1.1.0**, SQLite release archive
+- Hydra **v2.2.0**, SQLite release archive
+- `github.com/mxschmitt/playwright-go` **v0.6100.0**
+- embedded Playwright CLI **1.61.1**
+- managed Chromium revision **1228**, Chromium **149.0.7827.55**
+- managed FFmpeg revision **1011**
+
+The Playwright binding, CLI, browser, and installer command are one matched version set. The suite never selects Chrome from `PATH`.
+
+### Ory archives and checksums
+
+Hashes are pinned in `artifacts.go` from the official Kratos and Hydra release `checksums.txt` files.
+
+| Platform | Kratos archive / SHA-256 | Hydra archive / SHA-256 |
+|---|---|---|
+| linux/amd64 | `kratos_1.1.0-linux_sqlite_64bit.tar.gz` / `6fb3077252dde7578c3100d2cd4eb52364ca6b3c1b0b76987e6d586e29008cbd` | `hydra_2.2.0-linux_sqlite_64bit.tar.gz` / `0fe0539fa452496ac5d98b558f93eb2dbb4cf43733da0b09f8f2bdb4445fc31e` |
+| linux/arm64 | `kratos_1.1.0-linux_sqlite_arm64.tar.gz` / `fde8a1a1aebd153baff88b1232e0c2a34fdaaafe90b5364f4ea580151e74898e` | `hydra_2.2.0-linux_sqlite_arm64.tar.gz` / `c499ffdaae0f2ab85eff0567214734515b741a393bef89115c16018f4dc0560d` |
+| darwin/amd64 | `kratos_1.1.0-macOS_sqlite_64bit.tar.gz` / `ebdc94f27cb6e6a3087ed756accfb7837465ac8e30af9433b4414101814f7769` | `hydra_2.2.0-macOS_sqlite_64bit.tar.gz` / `3d40ca8e99e2a6d840130928d5e0245212dba0eea9c26a0d7186ebb4382e673d` |
+| darwin/arm64 | `kratos_1.1.0-macOS_sqlite_arm64.tar.gz` / `6681d7b15dd04686d10764750ce3ad69672b3962553223399a3a315ba5370517` | `hydra_2.2.0-macOS_sqlite_arm64.tar.gz` / `89732ad1494c57ea39348f62dc5ef5c48de129cd205b17cb12bb67ad27094bb7` |
+
+These four Linux/macOS architecture combinations are the supported selection matrix. Windows and every other `GOOS/GOARCH` fail before downloads, builds, or service startup. Selection and compile checks do not constitute a native real-browser result. The complete native online/offline suite and automated artifact-format checks have been exercised on Linux amd64; Linux arm64 and both macOS rows remain pending and must not be described as empirically green.
+
+## Prerequisites and installation
+
+Required locally:
+
+1. Go 1.22 or newer, with access to the normal Go module cache on first use.
+2. GitHub network access for an uncached Ory archive.
+3. Playwright-managed Chromium and FFmpeg.
+4. On Linux, the host libraries required by Chromium.
+
+Install the exactly matched browser runtime:
+
+From the `auth-ui` checkout directory:
+
+```sh
+cd /path/to/repository/auth-ui
+make install-e2e-browser
+```
+
+On a Linux host that lacks Chromium system libraries, install the browser and Playwright-recommended OS packages (the package-manager step may require privileges):
+
+```sh
+make install-e2e-browser-deps
+```
+
+No installer runs during ordinary `go test ./...`, `go vet ./...`, `make test`, builds, or image publishing.
+
+## Commands
+
+Fast, untagged tests and vet (no Ory or browser process startup):
+
+```sh
+make test
+```
+
+Install/check the pinned browser, then run the complete tagged suite:
+
+```sh
+make test-e2e
+```
+
+Run from already populated caches without invoking the online browser installer target:
+
+```sh
+make test-e2e-offline
+```
+
+The suite is deliberately serial: it starts one Kratos process, one Hydra process, one fresh `auth-ui` binary, one Playwright driver, and one Chromium process, then creates an isolated browser context for each test. It does not call `t.Parallel`. Make keeps Go's hard `-timeout=10m` contract. The harness starts its **9-minute internal deadline before stack setup**, so the deadline covers archive preparation, application build, service/browser/UI setup, and test execution before timeout cleanup begins, even though Go starts its own alarm inside `m.Run`. The harness therefore begins timeout cleanup at least one minute before Go's alarm. The shorter `AUTH_UI_E2E_WATCHDOG_TIMEOUT` override is reserved for the harness's timeout subprocess regressions; ordinary runs should retain the documented 9-minute deadline. A warm-cache full run is now approximately 60–65 seconds on the implementation Linux amd64 host because the two nested real watchdog regressions deliberately consume most of that duration; first runs and other machines can be slower.
+
+For focused development:
+
+```sh
+go test -count=1 ./e2e
+go test -tags=e2e -count=1 -run '^TestHydra' -timeout=10m -v ./e2e
+```
+
+The first command runs helper unit tests only. The second requires the installed browser and Ory archives.
+
+## Downloads, caches, and offline behavior
+
+On a cache miss, the harness downloads the selected official Kratos and Hydra release archives from GitHub, enforces a size bound, verifies the pinned SHA-256, and publishes atomically. Every cache reuse recomputes the hash.
+
+The default Ory archive cache is repository-local:
+
+```text
+e2e/cache/ory/<service>/<version>/<archive>
+```
+
+Override its root when needed:
+
+```sh
+AUTH_UI_E2E_CACHE_DIR=/absolute/cache make test-e2e
+AUTH_UI_E2E_CACHE_DIR=/absolute/cache make test-e2e-offline
+```
+
+`AUTH_UI_E2E_OFFLINE=1` disables Ory downloads and reports the missing/invalid path and expected hash. `make test-e2e-offline` intentionally does not depend on `install-e2e-browser`; therefore the Go modules, Playwright driver, Chromium, FFmpeg, Ory archives, and Linux host libraries must already be available. A first-ever run needs network access for every missing Go-module, Ory, Playwright-driver, or browser cache entry.
+
+Playwright's default cache locations are:
+
+| Host | Playwright driver | Managed browsers/FFmpeg |
+|---|---|---|
+| Linux | `~/.cache/ms-playwright-go/1.61.1` | `~/.cache/ms-playwright` |
+| macOS | `~/Library/Caches/ms-playwright-go/1.61.1` | `~/Library/Caches/ms-playwright` |
+
+The Linux paths follow the normal user cache root (for example, `$XDG_CACHE_HOME` when configured). `PLAYWRIGHT_DRIVER_PATH` and `PLAYWRIGHT_BROWSERS_PATH` may point to pre-populated matching caches. Do not point them at a different Playwright release or a system browser. Go honors its standard `GOMODCACHE`/`GOCACHE` settings.
+
+## Workspaces and overrides
+
+Each invocation creates a temporary workspace using the operating system's temporary directory, named like:
+
+```text
+<os-temp>/auth-ui-e2e-*/
+  bin/{auth-ui,kratos,hydra}
+  config/{identity.schema.json,kratos.yml,hydra.yml}
+  logs/{auth-ui.log,kratos.log,hydra.log}
+```
+
+The workspace is removed after success. It is retained after setup/test failure, and `AUTH_UI_E2E_KEEP_TMP=1` retains it after success. The harness prints retained paths when relevant. All generated service and callback URLs use dynamically allocated `127.0.0.1` ports; no fixed client, identity, port, or external origin is required.
+
+## Retained artifacts and sensitivity
+
+Every tagged test retains one artifact set on success and failure under:
+
+```text
+e2e/artifacts/<run-id>/
+  run.json
+  services/{auth-ui,kratos,hydra}.log
+  <test-name>/
+    screenshots/*.png
+    video.webm
+    trace.zip
+    session.json
+```
+
+Use `AUTH_UI_E2E_ARTIFACT_DIR=/absolute/path` to change the run-artifact root. Screenshots, video, traces, DOM/network snapshots, and upstream logs can contain generated credentials, cookies, OAuth challenges, codes, or tokens. Treat the entire artifact tree as **sensitive local test data**; do not publish or attach it without review. Both the default cache and artifact directories are ignored by Git.
+
+After inspecting representative PNG, WebM, trace, and metadata files, remove only default retained runs with:
+
+```sh
+make clean-e2e-artifacts
+```
+
+That target deletes exactly `e2e/artifacts/`. It does not clear `e2e/cache`, Playwright caches, an `AUTH_UI_E2E_ARTIFACT_DIR` override, fixtures, or ordinary build output. No test or ordinary clean target deletes artifacts automatically.
+
+## Cleanup and troubleshooting
+
+The harness registers aggregate lifecycle ownership before setup and records partial stack and Playwright ownership as soon as each becomes available. Service creation and cleanup use one ownership lock across the cleanup-state check, OS process start, and slot publication, so cleanup either prevents a new spawn or observes it. After `m.Run`, normal cleanup must atomically stop and claim the watchdog before cleanup begins; if the timer already fired, timeout cleanup owns the terminal status and exit. Browser sessions use the same claim model: a normal finalization claimed before timeout finishes exactly once and is awaited, while a timeout-claimed session is finalized as failed with attempted failure/final screenshots, trace closure, context/video finalization, and failed metadata. Timeout cleanup then closes owned callback listeners, stops services and browser/driver, copies bounded redacted service logs, records `watchdog_timeout` in `run.json`, retains available workspace/artifact paths, and exits nonzero. Both timeout-triggered cleanup and normal post-`m.Run` cleanup give protocol cleanup 45 seconds. If that bound expires, the emergency path directly kills every recorded service group and every discoverable driver/browser descendant without relying on Playwright protocols. Emergency termination has a separate grace of at most 5 seconds, with an unconditional exit 125 guard armed before descendant enumeration so even a blocked external `ps` command cannot delay final exit indefinitely.
+
+This pre-timeout cleanup covers stalls while the Go test process and its cleanup goroutine can still run. It cannot guarantee cleanup after `SIGKILL`, host shutdown, kernel failure, or another abrupt OS-level termination that prevents the harness from executing. After such an interrupted run, inspect the printed workspace and service logs and verify no process whose command references that workspace remains before deleting it.
+
+Common failures:
+
+- **Unsupported E2E platform:** use Linux/macOS on amd64/arm64. Windows is intentionally unsupported.
+- **Offline cache missing or invalid:** run `make test-e2e` online once with the same `AUTH_UI_E2E_CACHE_DIR`, or place the exact official archive at the reported path; the hash must match.
+- **Playwright driver/browser missing or mismatched:** run `make install-e2e-browser` with the repository's Go environment. Do not substitute system Chrome.
+- **Chromium cannot launch on Linux:** run `make install-e2e-browser-deps` with appropriate package-manager privileges.
+- **GitHub or Go proxy unavailable:** retry when online or populate the Ory, Playwright, and Go caches in advance.
+- **Readiness timeout or early process exit:** inspect `services/*.log` and the retained workspace logs. Port bind conflicts are retried only for owned startup attempts.
+- **Trace inspection:** use the trace viewer from the same Playwright 1.61.1 toolchain; traces from this suite are sensitive.
+- **Artifact growth:** inspect what is needed, then run the explicit cleanup target. Caches remain reusable offline.
+
+## Intentional non-goals
+
+This suite does not cover or introduce CI, Docker/Compose, PostgreSQL, Windows, system browsers, Firefox/WebKit, parallel stacks, pixel baselines, accessibility audits, recovery, verification, settings UI, MFA, social login, registration-disabled mode, PKCE, refresh tokens, revocation, introspection, consent rejection, Hydra logout, device/client-credentials flows, or a public password-change API. It does not change product handlers, templates, selectors, styles, or static assets.
diff --git a/core/auth/ui/e2e/api_client.go b/core/auth/ui/e2e/api_client.go
new file mode 100644
index 0000000..4f6c987
--- /dev/null
+++ b/core/auth/ui/e2e/api_client.go
@@ -0,0 +1,187 @@
+package e2e
+
+import (
+	"bytes"
+	"context"
+	"encoding/json"
+	"fmt"
+	"io"
+	"net/http"
+	"net/url"
+	"strings"
+	"time"
+)
+
+const maxDirectAPIResponse = 32 << 10
+
+type directAPIClient struct {
+	client       *http.Client
+	kratosPublic string
+	kratosAdmin  string
+}
+
+type kratosIdentity struct {
+	ID       string `json:"id"`
+	SchemaID string `json:"schema_id"`
+	State    string `json:"state"`
+	Traits   struct {
+		Username string `json:"username"`
+	} `json:"traits"`
+}
+
+type kratosSession struct {
+	Active   bool           `json:"active"`
+	Identity kratosIdentity `json:"identity"`
+}
+
+func newDirectAPIClient(kratosPublic, kratosAdmin string) *directAPIClient {
+	return &directAPIClient{
+		client:       &http.Client{Timeout: 10 * time.Second},
+		kratosPublic: strings.TrimRight(kratosPublic, "/"),
+		kratosAdmin:  strings.TrimRight(kratosAdmin, "/"),
+	}
+}
+
+func (c *directAPIClient) close() {
+	if c != nil && c.client != nil {
+		c.client.CloseIdleConnections()
+	}
+}
+
+func (c *directAPIClient) kratosWhoAmI(ctx context.Context, cookies []*http.Cookie) (kratosSession, bool, error) {
+	var session kratosSession
+	status, body, err := c.get(ctx, c.kratosPublic+"/sessions/whoami", cookies)
+	if err != nil {
+		return session, false, err
+	}
+	if status == http.StatusUnauthorized {
+		return session, false, nil
+	}
+	if status != http.StatusOK {
+		return session, false, unexpectedDirectAPIStatus("GET", "/sessions/whoami", status, body)
+	}
+	if err := json.Unmarshal(body, &session); err != nil {
+		return session, false, fmt.Errorf("decode Kratos whoami response: invalid JSON")
+	}
+	if !session.Active {
+		return session, false, fmt.Errorf("Kratos whoami response reported an inactive session")
+	}
+	if session.Identity.ID == "" || session.Identity.SchemaID == "" || session.Identity.State != "active" || session.Identity.Traits.Username == "" {
+		return session, false, fmt.Errorf("Kratos whoami response contained an inactive or incomplete identity")
+	}
+	return session, true, nil
+}
+
+func (c *directAPIClient) kratosIdentitiesByUsername(ctx context.Context, username string) ([]kratosIdentity, error) {
+	endpoint := c.kratosAdmin + "/admin/identities?page_size=500"
+	status, body, err := c.get(ctx, endpoint, nil)
+	if err != nil {
+		return nil, err
+	}
+	if status != http.StatusOK {
+		return nil, unexpectedDirectAPIStatus("GET", "/admin/identities", status, body)
+	}
+	var identities []kratosIdentity
+	if err := json.Unmarshal(body, &identities); err != nil {
+		return nil, fmt.Errorf("decode Kratos identities response: invalid JSON")
+	}
+	matching := make([]kratosIdentity, 0, 1)
+	for _, identity := range identities {
+		if identity.Traits.Username == username {
+			matching = append(matching, identity)
+		}
+	}
+	return matching, nil
+}
+
+func (c *directAPIClient) get(ctx context.Context, endpoint string, cookies []*http.Cookie) (int, []byte, error) {
+	ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
+	defer cancel()
+	req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil)
+	if err != nil {
+		return 0, nil, fmt.Errorf("construct bounded direct API GET %s", sanitizedEndpointPath(endpoint))
+	}
+	for _, cookie := range cookies {
+		if cookie != nil {
+			req.AddCookie(cookie)
+		}
+	}
+	return c.do(ctx, req)
+}
+
+func (c *directAPIClient) postJSON(ctx context.Context, endpoint string, body []byte) (int, []byte, error) {
+	ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
+	defer cancel()
+	req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint, bytes.NewReader(body))
+	if err != nil {
+		return 0, nil, fmt.Errorf("construct bounded direct API POST %s", sanitizedEndpointPath(endpoint))
+	}
+	req.Header.Set("Content-Type", "application/json")
+	return c.do(ctx, req)
+}
+
+func (c *directAPIClient) do(ctx context.Context, req *http.Request) (int, []byte, error) {
+	resp, err := c.client.Do(req)
+	if err != nil {
+		if ctx.Err() != nil {
+			return 0, nil, fmt.Errorf("direct API %s %s: %w", req.Method, sanitizedEndpointPath(req.URL.String()), ctx.Err())
+		}
+		return 0, nil, fmt.Errorf("direct API %s %s failed", req.Method, sanitizedEndpointPath(req.URL.String()))
+	}
+	defer resp.Body.Close()
+	body, err := io.ReadAll(io.LimitReader(resp.Body, maxDirectAPIResponse+1))
+	if err != nil {
+		return 0, nil, fmt.Errorf("read direct API response %s: %w", sanitizedEndpointPath(req.URL.String()), err)
+	}
+	if len(body) > maxDirectAPIResponse {
+		return 0, nil, fmt.Errorf("direct API response %s exceeds %d bytes", sanitizedEndpointPath(req.URL.String()), maxDirectAPIResponse)
+	}
+	return resp.StatusCode, body, nil
+}
+
+func unexpectedDirectAPIStatus(method, path string, status int, body []byte) error {
+	return fmt.Errorf("direct API %s %s returned status %d: %s", method, path, status, sanitizedResponseDiagnostic(body))
+}
+
+func sanitizedEndpointPath(raw string) string {
+	u, err := url.Parse(raw)
+	if err != nil || u.Path == "" {
+		return "endpoint"
+	}
+	return u.EscapedPath()
+}
+
+func sanitizedResponseDiagnostic(body []byte) string {
+	if len(body) == 0 {
+		return "empty response"
+	}
+	var value any
+	if json.Unmarshal(body, &value) != nil {
+		return "non-JSON response omitted"
+	}
+	value = redactJSONValue(value)
+	encoded, err := json.Marshal(value)
+	if err != nil {
+		return "JSON response omitted"
+	}
+	return string(encoded)
+}
+
+func redactJSONValue(value any) any {
+	switch typed := value.(type) {
+	case map[string]any:
+		for key, child := range typed {
+			typed[key] = redactJSONValue(child)
+		}
+		return typed
+	case []any:
+		for index, child := range typed {
+			typed[index] = redactJSONValue(child)
+		}
+		return typed
+	case string:
+		return "[REDACTED]"
+	default:
+		return value
+	}
+}
diff --git a/core/auth/ui/e2e/api_client_test.go b/core/auth/ui/e2e/api_client_test.go
new file mode 100644
index 0000000..f9201d9
--- /dev/null
+++ b/core/auth/ui/e2e/api_client_test.go
@@ -0,0 +1,179 @@
+package e2e
+
+import (
+	"context"
+	"fmt"
+	"io"
+	"net/http"
+	"net/http/httptest"
+	"strings"
+	"testing"
+)
+
+func TestDirectAPIKratosWhoAmIAndIdentityLookup(t *testing.T) {
+	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		switch r.URL.Path {
+		case "/sessions/whoami":
+			cookie, err := r.Cookie("ory_kratos_session")
+			if err != nil || cookie.Value != "accepted-session" {
+				http.Error(w, `{"error":"unauthorized"}`, http.StatusUnauthorized)
+				return
+			}
+			w.Header().Set("Content-Type", "application/json")
+			fmt.Fprint(w, `{"active":true,"identity":{"id":"identity-1","schema_id":"user","state":"active","traits":{"username":"wanted-user"}}}`)
+		case "/admin/identities":
+			if r.URL.Query().Get("page_size") != "500" {
+				t.Errorf("page_size=%q", r.URL.Query().Get("page_size"))
+			}
+			w.Header().Set("Content-Type", "application/json")
+			fmt.Fprint(w, `[{"id":"identity-1","schema_id":"user","state":"active","traits":{"username":"wanted-user"}},{"id":"identity-2","traits":{"username":"other-user"}}]`)
+		default:
+			http.NotFound(w, r)
+		}
+	}))
+	defer server.Close()
+
+	client := newDirectAPIClient(server.URL, server.URL)
+	defer client.close()
+	session, accepted, err := client.kratosWhoAmI(context.Background(), []*http.Cookie{{Name: "ory_kratos_session", Value: "accepted-session"}})
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !accepted || !session.Active || session.Identity.ID != "identity-1" || session.Identity.Traits.Username != "wanted-user" {
+		t.Fatalf("unexpected accepted whoami result: accepted=%v session=%+v", accepted, session)
+	}
+	identities, err := client.kratosIdentitiesByUsername(context.Background(), "wanted-user")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(identities) != 1 || identities[0].ID != session.Identity.ID || identities[0].SchemaID != "user" || identities[0].State != "active" {
+		t.Fatalf("matching identities=%+v", identities)
+	}
+}
+
+func TestDirectAPIKratosWhoAmIRejectsUnauthorizedSession(t *testing.T) {
+	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
+		w.WriteHeader(http.StatusUnauthorized)
+	}))
+	defer server.Close()
+	client := newDirectAPIClient(server.URL, server.URL)
+	defer client.close()
+
+	_, accepted, err := client.kratosWhoAmI(context.Background(), nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if accepted {
+		t.Fatal("unauthorized Kratos response was accepted")
+	}
+}
+
+func TestDirectAPIKratosWhoAmIRejectsNonUnauthorizedResponses(t *testing.T) {
+	tests := []struct {
+		name   string
+		status int
+		body   string
+	}{
+		{name: "forbidden", status: http.StatusForbidden, body: `{"error":"secret-forbidden-detail"}`},
+		{name: "inactive", status: http.StatusOK, body: `{"active":false,"identity":{"id":"identity-1","schema_id":"user","state":"active","traits":{"username":"user"}}}`},
+		{name: "incomplete", status: http.StatusOK, body: `{"active":true,"identity":{"schema_id":"user","state":"active","traits":{"username":"user"}}}`},
+	}
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
+				w.WriteHeader(test.status)
+				fmt.Fprint(w, test.body)
+			}))
+			defer server.Close()
+			client := newDirectAPIClient(server.URL, server.URL)
+			defer client.close()
+
+			_, accepted, err := client.kratosWhoAmI(context.Background(), nil)
+			if err == nil {
+				t.Fatal("non-401 Kratos response did not produce an error")
+			}
+			if accepted {
+				t.Fatal("invalid Kratos response was accepted")
+			}
+			if strings.Contains(err.Error(), "secret-forbidden-detail") {
+				t.Fatalf("whoami error leaked response detail: %v", err)
+			}
+		})
+	}
+}
+
+func TestDirectAPIPostJSONSetsContentType(t *testing.T) {
+	const requestBody = `{"username":"test-user","password":"local-secret"}`
+	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		if r.Method != http.MethodPost {
+			t.Errorf("method=%s", r.Method)
+		}
+		if got := r.Header.Get("Content-Type"); got != "application/json" {
+			t.Errorf("Content-Type=%q", got)
+		}
+		body, err := io.ReadAll(r.Body)
+		if err != nil {
+			t.Errorf("read request: %v", err)
+		}
+		if string(body) != requestBody {
+			t.Error("POST body did not round trip")
+		}
+		w.Header().Set("Content-Type", "application/json")
+		w.WriteHeader(http.StatusCreated)
+		fmt.Fprint(w, `{"id":"identity-1"}`)
+	}))
+	defer server.Close()
+	client := newDirectAPIClient(server.URL, server.URL)
+	defer client.close()
+
+	status, body, err := client.postJSON(context.Background(), server.URL+"/identities", []byte(requestBody))
+	if err != nil {
+		t.Fatal(err)
+	}
+	if status != http.StatusCreated || string(body) != `{"id":"identity-1"}` {
+		t.Fatalf("unexpected POST response: status=%d body=%s", status, sanitizedResponseDiagnostic(body))
+	}
+}
+
+func TestDirectAPIMalformedRequestDoesNotLeakQuery(t *testing.T) {
+	client := newDirectAPIClient("http://127.0.0.1", "http://127.0.0.1")
+	defer client.close()
+	const secret = "secret-query-value"
+	_, _, err := client.get(context.Background(), "http://127.0.0.1/%zz?token="+secret, nil)
+	if err == nil {
+		t.Fatal("malformed request URL was accepted")
+	}
+	if strings.Contains(err.Error(), secret) || strings.Contains(err.Error(), "token=") || strings.Contains(err.Error(), "%zz") {
+		t.Fatalf("request-construction diagnostic leaked URL/query material: %v", err)
+	}
+	if err.Error() != "construct bounded direct API GET endpoint" {
+		t.Fatalf("unexpected safe request-construction diagnostic: %v", err)
+	}
+}
+
+func TestDirectAPIResponseBoundAndDiagnosticRedaction(t *testing.T) {
+	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
+		w.WriteHeader(http.StatusBadGateway)
+		fmt.Fprint(w, strings.Repeat("x", maxDirectAPIResponse+1))
+	}))
+	defer server.Close()
+	client := newDirectAPIClient(server.URL, server.URL)
+	defer client.close()
+
+	if _, _, err := client.get(context.Background(), server.URL+"/oversized?token=not-for-diagnostics", nil); err == nil || !strings.Contains(err.Error(), "exceeds") || strings.Contains(err.Error(), "not-for-diagnostics") {
+		t.Fatalf("bounded response error=%v", err)
+	}
+
+	diagnostic := sanitizedResponseDiagnostic([]byte(`{"error":"safe context","password":"secret-password","nested":{"csrfToken":"secret-csrf","code":"secret-code","flow":"secret-flow"}}`))
+	for _, secret := range []string{"secret-password", "secret-csrf", "secret-code", "secret-flow"} {
+		if strings.Contains(diagnostic, secret) {
+			t.Fatalf("diagnostic leaked secret: %s", diagnostic)
+		}
+	}
+	if strings.Contains(diagnostic, "safe context") || strings.Count(diagnostic, "[REDACTED]") != 5 {
+		t.Fatalf("unexpected sanitized diagnostic: %s", diagnostic)
+	}
+	if got := sanitizedResponseDiagnostic([]byte("password=secret")); got != "non-JSON response omitted" {
+		t.Fatalf("non-JSON diagnostic=%q", got)
+	}
+}
diff --git a/core/auth/ui/e2e/api_password_test.go b/core/auth/ui/e2e/api_password_test.go
new file mode 100644
index 0000000..e62c041
--- /dev/null
+++ b/core/auth/ui/e2e/api_password_test.go
@@ -0,0 +1,258 @@
+//go:build e2e
+
+package e2e
+
+import (
+	"context"
+	"encoding/json"
+	"net/http"
+	"net/url"
+	"strings"
+	"testing"
+	"time"
+
+	playwright "github.com/mxschmitt/playwright-go"
+)
+
+const (
+	usernameLengthMessage      = "Username must be at least 3 characters long."
+	passwordLengthMessage      = "Password must be at least 20 characters long."
+	passwordCompositionMessage = "Password must contain at least one digit, lower&upper case and special characters"
+	usernameUnavailableMessage = "Username is not available."
+	passwordChangedMessage     = "Password changed successfully."
+)
+
+type identityAPIResponse struct {
+	ID string `json:"id"`
+}
+
+type identityAPIErrors struct {
+	Errors []struct {
+		Field   string `json:"field"`
+		Message string `json:"message"`
+	} `json:"errors"`
+}
+
+func TestIdentityAPI(t *testing.T) {
+	session := newKratosTestSession(t)
+	client := newDirectAPIClient(testStack.KratosURL, testStack.KratosAdmin)
+	defer client.close()
+	username, password := uniqueKratosCredentials(t)
+
+	status, _, err := client.postJSON(context.Background(), testStack.APIURL+"/identities", []byte(`{"username":`))
+	if err != nil {
+		t.Fatal(err)
+	}
+	if status != http.StatusBadRequest {
+		t.Fatalf("malformed identity JSON returned status %d, want 400", status)
+	}
+
+	status, body := postIdentityJSON(t, client, "x", "short")
+	if status != http.StatusBadRequest {
+		t.Fatalf("invalid identity fields returned status %d, want 400: %s", status, sanitizedResponseDiagnostic(body))
+	}
+	assertIdentityAPIErrors(t, body, map[string][]string{
+		"username": {usernameLengthMessage},
+		"password": {passwordLengthMessage, passwordCompositionMessage},
+	})
+
+	status, body = postIdentityJSON(t, client, username+"-invalid", strings.Repeat("a", 24))
+	if status != http.StatusBadRequest {
+		t.Fatalf("composition-invalid password returned status %d, want 400: %s", status, sanitizedResponseDiagnostic(body))
+	}
+	assertIdentityAPIErrors(t, body, map[string][]string{
+		"password": {passwordCompositionMessage},
+	})
+
+	status, body = postIdentityJSON(t, client, username, password)
+	if status != http.StatusOK {
+		t.Fatalf("valid identity creation returned status %d, want 200: %s", status, sanitizedResponseDiagnostic(body))
+	}
+	var created identityAPIResponse
+	if err := json.Unmarshal(body, &created); err != nil || created.ID == "" {
+		t.Fatal("valid identity creation did not return a non-empty JSON id")
+	}
+
+	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+	identities, err := client.kratosIdentitiesByUsername(ctx, username)
+	cancel()
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(identities) != 1 || identities[0].ID != created.ID || identities[0].SchemaID != "user" || identities[0].State != "active" || identities[0].Traits.Username != username {
+		t.Fatal("Kratos Admin did not persist the API-created identity with its id, user schema, active state, and username")
+	}
+
+	status, body = postIdentityJSON(t, client, username, password)
+	if status != http.StatusBadRequest {
+		t.Fatalf("duplicate identity returned status %d, want 400: %s", status, sanitizedResponseDiagnostic(body))
+	}
+	assertIdentityAPIErrors(t, body, map[string][]string{
+		"username": {usernameUnavailableMessage},
+	})
+
+	openKratosForm(t, session.Page, testStack.UIURL+"/login", "/login")
+	checkpoint(t, session, "api-created-identity-login-form")
+	fillCredentials(t, session.Page, username, password)
+	clickButton(t, session.Page, "login")
+	assertGreeting(t, session.Page, username)
+	checkpoint(t, session, "api-created-identity-greeting")
+	whoami := assertAcceptedKratosSession(t, client, session)
+	if whoami.Identity.ID != created.ID || whoami.Identity.Traits.Username != username {
+		t.Fatal("browser login did not resolve to the API-created identity id and username")
+	}
+}
+
+func TestPasswordChange(t *testing.T) {
+	session := newKratosTestSession(t)
+	client := newDirectAPIClient(testStack.KratosURL, testStack.KratosAdmin)
+	defer client.close()
+	username, oldPassword := uniqueKratosCredentials(t)
+	_, newPassword := uniqueKratosCredentials(t)
+
+	if _, err := session.Page.Goto(testStack.UIURL + "/settings"); err != nil {
+		t.Fatal(err)
+	}
+	assertKratosForm(t, session.Page, "/login")
+	if count, err := session.Page.GetByRole("button", playwright.PageGetByRoleOptions{Name: "change password", Exact: playwright.Bool(true)}).Count(); err != nil || count != 0 {
+		t.Fatalf("unauthenticated change-password guard exposed its form: count=%d err=%v", count, err)
+	}
+	checkpoint(t, session, "unauthenticated-change-password-guard")
+
+	registerThroughBrowser(t, session, username, oldPassword, "password-change-registration")
+	original := assertAcceptedKratosSession(t, client, session)
+	openChangePasswordForm(t, session.Page, username)
+
+	if err := session.Page.Locator(`input[name="password"]`).Fill("short"); err != nil {
+		t.Fatal("fill invalid replacement password")
+	}
+	clickButton(t, session.Page, "change password")
+	assertChangePasswordForm(t, session.Page, username)
+	assertVisibleExactText(t, session.Page, passwordLengthMessage)
+	assertVisibleExactText(t, session.Page, passwordCompositionMessage)
+	checkpoint(t, session, "invalid-password-change-validation")
+
+	logoutThroughBrowser(t, session)
+	checkpoint(t, session, "old-password-login-after-invalid-update")
+	fillCredentials(t, session.Page, username, oldPassword)
+	clickButton(t, session.Page, "login")
+	assertGreeting(t, session.Page, username)
+	oldLogin := assertAcceptedKratosSession(t, client, session)
+	if oldLogin.Identity.ID != original.Identity.ID || oldLogin.Identity.Traits.Username != username {
+		t.Fatal("old password after invalid update did not resolve to the original identity")
+	}
+	checkpoint(t, session, "old-password-accepted-after-invalid-update")
+
+	openChangePasswordForm(t, session.Page, username)
+	if err := session.Page.Locator(`input[name="password"]`).Fill(newPassword); err != nil {
+		t.Fatal("fill valid replacement password")
+	}
+	clickButton(t, session.Page, "change password")
+	assertVisibleExactText(t, session.Page, passwordChangedMessage)
+	checkpoint(t, session, "password-change-success")
+
+	logoutThroughBrowser(t, session)
+	checkpoint(t, session, "old-password-login-after-replacement")
+	fillCredentials(t, session.Page, username, oldPassword)
+	clickButton(t, session.Page, "login")
+	assertKratosForm(t, session.Page, "/login")
+	assertNoAcceptedKratosSession(t, client, session)
+	checkpoint(t, session, "old-password-rejected")
+
+	fillCredentials(t, session.Page, username, newPassword)
+	clickButton(t, session.Page, "login")
+	assertGreeting(t, session.Page, username)
+	accepted := assertAcceptedKratosSession(t, client, session)
+	if accepted.Identity.ID != original.Identity.ID || accepted.Identity.Traits.Username != username {
+		t.Fatal("replacement password did not preserve the original identity id and username")
+	}
+	checkpoint(t, session, "new-password-accepted")
+}
+
+func postIdentityJSON(t *testing.T, client *directAPIClient, username, password string) (int, []byte) {
+	t.Helper()
+	body, err := json.Marshal(map[string]string{"username": username, "password": password})
+	if err != nil {
+		t.Fatal("encode identity API request")
+	}
+	status, response, err := client.postJSON(context.Background(), testStack.APIURL+"/identities", body)
+	if err != nil {
+		t.Fatal(err)
+	}
+	return status, response
+}
+
+func assertIdentityAPIErrors(t *testing.T, body []byte, expected map[string][]string) {
+	t.Helper()
+	var response identityAPIErrors
+	if err := json.Unmarshal(body, &response); err != nil {
+		t.Fatal("identity API error response was not valid JSON")
+	}
+	remaining := make(map[string]map[string]bool, len(expected))
+	total := 0
+	for field, messages := range expected {
+		remaining[field] = make(map[string]bool, len(messages))
+		for _, message := range messages {
+			remaining[field][message] = true
+			total++
+		}
+	}
+	if len(response.Errors) != total {
+		t.Fatalf("identity API returned %d validation errors, want %d", len(response.Errors), total)
+	}
+	for _, apiError := range response.Errors {
+		messages, ok := remaining[apiError.Field]
+		if !ok || !messages[apiError.Message] {
+			t.Fatalf("identity API returned an unexpected validation error for field %q", apiError.Field)
+		}
+		delete(messages, apiError.Message)
+	}
+	for field, messages := range remaining {
+		if len(messages) != 0 {
+			t.Fatalf("identity API omitted an expected validation error for field %q", field)
+		}
+	}
+}
+
+func openChangePasswordForm(t *testing.T, page playwright.Page, username string) {
+	t.Helper()
+	link := page.Locator(`a[href="/settings"]`)
+	if err := link.Click(); err != nil {
+		t.Fatal("open change-password flow from the logged-in user page")
+	}
+	assertChangePasswordForm(t, page, username)
+}
+
+func assertChangePasswordForm(t *testing.T, page playwright.Page, username string) {
+	t.Helper()
+	u, err := url.Parse(page.URL())
+	if err != nil || u.Scheme+"://"+u.Host != testStack.UIURL || u.Path != "/settings" || u.Query().Get("flow") == "" {
+		t.Fatal("authenticated password form was not rendered through a Kratos settings flow")
+	}
+	password := page.Locator(`input[name="password"]`)
+	if err := password.WaitFor(playwright.LocatorWaitForOptions{State: playwright.WaitForSelectorStateVisible, Timeout: playwright.Float(10_000)}); err != nil {
+		t.Fatalf("change-password field did not become visible: %v", err)
+	}
+	usernameInput := page.Locator(`input[name="username"]`)
+	if count, err := usernameInput.Count(); err != nil || count != 1 {
+		t.Fatalf("change-password form username field count=%d err=%v", count, err)
+	}
+	if value, err := usernameInput.InputValue(); err != nil || value != username {
+		t.Fatal("change-password form did not retain the authenticated username")
+	}
+}
+
+func assertVisibleExactText(t *testing.T, page playwright.Page, text string) {
+	t.Helper()
+	if err := page.GetByText(text, playwright.PageGetByTextOptions{Exact: playwright.Bool(true)}).WaitFor(playwright.LocatorWaitForOptions{State: playwright.WaitForSelectorStateVisible, Timeout: playwright.Float(10_000)}); err != nil {
+		t.Fatalf("expected product message was not visible: %v", err)
+	}
+}
+
+func logoutThroughBrowser(t *testing.T, session *browserSession) {
+	t.Helper()
+	if _, err := session.Page.Goto(testStack.UIURL + "/logout"); err != nil {
+		t.Fatal(err)
+	}
+	assertKratosForm(t, session.Page, "/login")
+}
diff --git a/core/auth/ui/e2e/archive.go b/core/auth/ui/e2e/archive.go
new file mode 100644
index 0000000..f9b85dd
--- /dev/null
+++ b/core/auth/ui/e2e/archive.go
@@ -0,0 +1,104 @@
+package e2e
+
+import (
+	"archive/tar"
+	"compress/gzip"
+	"context"
+	"errors"
+	"fmt"
+	"io"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"strings"
+	"time"
+)
+
+func extractBinary(archivePath, destinationDir, expectedName string) (string, error) {
+	f, err := os.Open(archivePath)
+	if err != nil {
+		return "", err
+	}
+	defer f.Close()
+	gz, err := gzip.NewReader(f)
+	if err != nil {
+		return "", fmt.Errorf("open gzip archive: %w", err)
+	}
+	defer gz.Close()
+
+	if err := os.MkdirAll(destinationDir, 0o755); err != nil {
+		return "", err
+	}
+	var found []byte
+	tr := tar.NewReader(gz)
+	for {
+		h, err := tr.Next()
+		if errors.Is(err, io.EOF) {
+			break
+		}
+		if err != nil {
+			return "", fmt.Errorf("read tar archive: %w", err)
+		}
+		clean := filepath.Clean(h.Name)
+		if filepath.IsAbs(h.Name) || clean == ".." || strings.HasPrefix(clean, ".."+string(filepath.Separator)) {
+			return "", fmt.Errorf("unsafe archive path %q", h.Name)
+		}
+		if filepath.Base(clean) != expectedName {
+			continue
+		}
+		if h.Typeflag != tar.TypeReg && h.Typeflag != tar.TypeRegA {
+			return "", fmt.Errorf("expected executable %q is not a regular file", h.Name)
+		}
+		if found != nil {
+			return "", fmt.Errorf("archive contains multiple %q executables", expectedName)
+		}
+		if h.Size < 1 || h.Size > 512<<20 {
+			return "", fmt.Errorf("invalid executable size %d", h.Size)
+		}
+		found, err = io.ReadAll(io.LimitReader(tr, h.Size+1))
+		if err != nil {
+			return "", err
+		}
+		if int64(len(found)) != h.Size {
+			return "", fmt.Errorf("truncated executable %q", h.Name)
+		}
+	}
+	if found == nil {
+		return "", fmt.Errorf("archive does not contain expected executable %q", expectedName)
+	}
+	destination := filepath.Join(destinationDir, expectedName)
+	if err := os.WriteFile(destination, found, 0o755); err != nil {
+		return "", err
+	}
+	if err := os.Chmod(destination, 0o755); err != nil {
+		return "", err
+	}
+	return destination, nil
+}
+
+func verifyBinaryVersion(path, expected string) error {
+	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+	defer cancel()
+	out, err := exec.CommandContext(ctx, path, "version").CombinedOutput()
+	if ctx.Err() != nil {
+		return fmt.Errorf("verify %s version: %w", filepath.Base(path), ctx.Err())
+	}
+	if err != nil {
+		return fmt.Errorf("verify %s version: %w (%s)", filepath.Base(path), err, boundedText(out, 2048))
+	}
+	if !versionOutputMatches(out, expected) {
+		return fmt.Errorf("unexpected %s version: expected %s, got %s", filepath.Base(path), expected, boundedText(out, 2048))
+	}
+	return nil
+}
+
+func versionOutputMatches(output []byte, expected string) bool {
+	withoutV := strings.TrimPrefix(expected, "v")
+	for _, field := range strings.Fields(string(output)) {
+		field = strings.Trim(field, " \t\r\n,;:()[]{}")
+		if field == expected || field == withoutV {
+			return true
+		}
+	}
+	return false
+}
diff --git a/core/auth/ui/e2e/archive_test.go b/core/auth/ui/e2e/archive_test.go
new file mode 100644
index 0000000..c9c9c91
--- /dev/null
+++ b/core/auth/ui/e2e/archive_test.go
@@ -0,0 +1,125 @@
+package e2e
+
+import (
+	"archive/tar"
+	"compress/gzip"
+	"os"
+	"path/filepath"
+	"strings"
+	"testing"
+)
+
+type tarEntry struct {
+	name string
+	body string
+	kind byte
+}
+
+func writeTarGz(t *testing.T, entries []tarEntry) string {
+	t.Helper()
+	path := filepath.Join(t.TempDir(), "fixture.tar.gz")
+	f, err := os.Create(path)
+	if err != nil {
+		t.Fatal(err)
+	}
+	gz := gzip.NewWriter(f)
+	tw := tar.NewWriter(gz)
+	for _, entry := range entries {
+		kind := entry.kind
+		if kind == 0 {
+			kind = tar.TypeReg
+		}
+		h := &tar.Header{Name: entry.name, Mode: 0o644, Size: int64(len(entry.body)), Typeflag: kind}
+		if err := tw.WriteHeader(h); err != nil {
+			t.Fatal(err)
+		}
+		if kind == tar.TypeReg {
+			if _, err := tw.Write([]byte(entry.body)); err != nil {
+				t.Fatal(err)
+			}
+		}
+	}
+	if err := tw.Close(); err != nil {
+		t.Fatal(err)
+	}
+	if err := gz.Close(); err != nil {
+		t.Fatal(err)
+	}
+	if err := f.Close(); err != nil {
+		t.Fatal(err)
+	}
+	return path
+}
+
+func TestExtractBinary(t *testing.T) {
+	workspace := t.TempDir()
+	archive := writeTarGz(t, []tarEntry{{name: "nested/kratos", body: "binary"}, {name: "README", body: "text"}})
+	path, err := extractBinary(archive, filepath.Join(workspace, "bin"), "kratos")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if filepath.Dir(path) != filepath.Join(workspace, "bin") {
+		t.Fatalf("extracted outside destination: %s", path)
+	}
+	info, err := os.Stat(path)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if info.Mode().Perm() != 0o755 {
+		t.Fatalf("mode=%o", info.Mode().Perm())
+	}
+}
+
+func TestExtractBinaryRejectsUnsafeArchives(t *testing.T) {
+	for _, name := range []string{"../kratos", "nested/../../kratos", "/absolute/kratos"} {
+		t.Run(strings.ReplaceAll(name, "/", "_"), func(t *testing.T) {
+			archive := writeTarGz(t, []tarEntry{{name: name, body: "bad"}})
+			if _, err := extractBinary(archive, t.TempDir(), "kratos"); err == nil || !strings.Contains(err.Error(), "unsafe archive path") {
+				t.Fatalf("error=%v", err)
+			}
+		})
+	}
+}
+
+func TestVersionOutputMatchesExactSemanticVersion(t *testing.T) {
+	for _, output := range []string{"Version:\tv1.1.0\n", "Version: 1.1.0\n"} {
+		if !versionOutputMatches([]byte(output), "v1.1.0") {
+			t.Errorf("expected match for %q", output)
+		}
+	}
+	for _, output := range []string{"Version: v11.1.0", "Version: v1.1.01", "commit-v1.1.0-extra"} {
+		if versionOutputMatches([]byte(output), "v1.1.0") {
+			t.Errorf("unexpected match for %q", output)
+		}
+	}
+}
+
+func TestExtractBinaryFailures(t *testing.T) {
+	t.Run("missing", func(t *testing.T) {
+		archive := writeTarGz(t, []tarEntry{{name: "other", body: "x"}})
+		if _, err := extractBinary(archive, t.TempDir(), "hydra"); err == nil || !strings.Contains(err.Error(), "does not contain") {
+			t.Fatalf("error=%v", err)
+		}
+	})
+	t.Run("multiple", func(t *testing.T) {
+		archive := writeTarGz(t, []tarEntry{{name: "a/hydra", body: "x"}, {name: "b/hydra", body: "y"}})
+		if _, err := extractBinary(archive, t.TempDir(), "hydra"); err == nil || !strings.Contains(err.Error(), "multiple") {
+			t.Fatalf("error=%v", err)
+		}
+	})
+	t.Run("not-regular", func(t *testing.T) {
+		archive := writeTarGz(t, []tarEntry{{name: "hydra", kind: tar.TypeSymlink}})
+		if _, err := extractBinary(archive, t.TempDir(), "hydra"); err == nil || !strings.Contains(err.Error(), "regular") {
+			t.Fatalf("error=%v", err)
+		}
+	})
+	t.Run("corrupt", func(t *testing.T) {
+		path := filepath.Join(t.TempDir(), "bad.tar.gz")
+		if err := os.WriteFile(path, []byte("not gzip"), 0o600); err != nil {
+			t.Fatal(err)
+		}
+		if _, err := extractBinary(path, t.TempDir(), "hydra"); err == nil {
+			t.Fatal("expected corrupt archive error")
+		}
+	})
+}
diff --git a/core/auth/ui/e2e/artifacts.go b/core/auth/ui/e2e/artifacts.go
new file mode 100644
index 0000000..fda096e
--- /dev/null
+++ b/core/auth/ui/e2e/artifacts.go
@@ -0,0 +1,212 @@
+package e2e
+
+import (
+	"context"
+	"crypto/sha256"
+	"encoding/hex"
+	"errors"
+	"fmt"
+	"io"
+	"net/http"
+	"os"
+	"path/filepath"
+	"runtime"
+	"strings"
+	"time"
+)
+
+const (
+	maxOryArchiveDownloadSize int64 = 512 << 20
+
+	kratosVersion        = "v1.1.0"
+	hydraVersion         = "v2.2.0"
+	playwrightVersion    = "v0.6100.0"
+	playwrightCLIVersion = "1.61.1"
+	chromiumRevision     = "1228"
+	chromiumVersion      = "149.0.7827.55"
+	ffmpegRevision       = "1011"
+)
+
+type releaseArtifact struct {
+	Service string
+	Version string
+	Archive string
+	SHA256  string
+	URL     string
+}
+
+type platformArtifacts struct {
+	Kratos releaseArtifact
+	Hydra  releaseArtifact
+}
+
+// Hashes are from the official release checksum manifests:
+// https://github.com/ory/kratos/releases/download/v1.1.0/checksums.txt
+// https://github.com/ory/hydra/releases/download/v2.2.0/checksums.txt
+var artifactPlatforms = map[string]platformArtifacts{
+	"linux/amd64":  platform("kratos_1.1.0-linux_sqlite_64bit.tar.gz", "6fb3077252dde7578c3100d2cd4eb52364ca6b3c1b0b76987e6d586e29008cbd", "hydra_2.2.0-linux_sqlite_64bit.tar.gz", "0fe0539fa452496ac5d98b558f93eb2dbb4cf43733da0b09f8f2bdb4445fc31e"),
+	"linux/arm64":  platform("kratos_1.1.0-linux_sqlite_arm64.tar.gz", "fde8a1a1aebd153baff88b1232e0c2a34fdaaafe90b5364f4ea580151e74898e", "hydra_2.2.0-linux_sqlite_arm64.tar.gz", "c499ffdaae0f2ab85eff0567214734515b741a393bef89115c16018f4dc0560d"),
+	"darwin/amd64": platform("kratos_1.1.0-macOS_sqlite_64bit.tar.gz", "ebdc94f27cb6e6a3087ed756accfb7837465ac8e30af9433b4414101814f7769", "hydra_2.2.0-macOS_sqlite_64bit.tar.gz", "3d40ca8e99e2a6d840130928d5e0245212dba0eea9c26a0d7186ebb4382e673d"),
+	"darwin/arm64": platform("kratos_1.1.0-macOS_sqlite_arm64.tar.gz", "6681d7b15dd04686d10764750ce3ad69672b3962553223399a3a315ba5370517", "hydra_2.2.0-macOS_sqlite_arm64.tar.gz", "89732ad1494c57ea39348f62dc5ef5c48de129cd205b17cb12bb67ad27094bb7"),
+}
+
+func platform(kratosArchive, kratosHash, hydraArchive, hydraHash string) platformArtifacts {
+	return platformArtifacts{
+		Kratos: releaseArtifact{"kratos", kratosVersion, kratosArchive, kratosHash, "https://github.com/ory/kratos/releases/download/" + kratosVersion + "/" + kratosArchive},
+		Hydra:  releaseArtifact{"hydra", hydraVersion, hydraArchive, hydraHash, "https://github.com/ory/hydra/releases/download/" + hydraVersion + "/" + hydraArchive},
+	}
+}
+
+func artifactsFor(goos, goarch string) (platformArtifacts, error) {
+	p, ok := artifactPlatforms[goos+"/"+goarch]
+	if !ok {
+		return platformArtifacts{}, fmt.Errorf("unsupported E2E platform %s/%s (supported: linux/amd64, linux/arm64, darwin/amd64, darwin/arm64)", goos, goarch)
+	}
+	return p, nil
+}
+
+func repositoryDir() (string, error) {
+	_, source, _, ok := runtime.Caller(0)
+	if !ok {
+		return "", errors.New("locate e2e source file")
+	}
+	dir := filepath.Dir(filepath.Dir(source))
+	if _, err := os.Stat(filepath.Join(dir, "go.mod")); err != nil {
+		return "", fmt.Errorf("locate auth-ui repository: %w", err)
+	}
+	return dir, nil
+}
+
+func cacheRoot(repo string) string {
+	if root := os.Getenv("AUTH_UI_E2E_CACHE_DIR"); root != "" {
+		return root
+	}
+	return filepath.Join(repo, "e2e", "cache")
+}
+
+func archiveCachePath(root string, artifact releaseArtifact) string {
+	return filepath.Join(root, "ory", artifact.Service, artifact.Version, artifact.Archive)
+}
+
+func ensureArchive(ctx context.Context, client *http.Client, root string, artifact releaseArtifact, offline bool) (string, error) {
+	return ensureArchiveWithLimit(ctx, client, root, artifact, offline, maxOryArchiveDownloadSize)
+}
+
+func ensureArchiveWithLimit(ctx context.Context, client *http.Client, root string, artifact releaseArtifact, offline bool, maxSize int64) (string, error) {
+	path := archiveCachePath(root, artifact)
+	valid, actual, err := validSHA256(path, artifact.SHA256)
+	if err != nil && !errors.Is(err, os.ErrNotExist) {
+		return "", err
+	}
+	if valid {
+		return path, nil
+	}
+	if offline {
+		return "", fmt.Errorf("offline E2E cache is missing or invalid: %s (expected sha256 %s, got %s); populate it with an online E2E run", path, artifact.SHA256, printableHash(actual))
+	}
+	if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
+		return "", err
+	}
+	unlock, err := acquireCacheLock(ctx, path+".lock")
+	if err != nil {
+		return "", fmt.Errorf("lock archive cache %s: %w", path, err)
+	}
+	defer unlock()
+
+	// Another harness process may have published a valid archive while this
+	// caller waited for the lock. Revalidate before removing the invalid path.
+	valid, actual, err = validSHA256(path, artifact.SHA256)
+	if err != nil && !errors.Is(err, os.ErrNotExist) {
+		return "", err
+	}
+	if valid {
+		return path, nil
+	}
+	if err := os.Remove(path); err != nil && !errors.Is(err, os.ErrNotExist) {
+		return "", fmt.Errorf("remove invalid cache file: %w", err)
+	}
+
+	req, err := http.NewRequestWithContext(ctx, http.MethodGet, artifact.URL, nil)
+	if err != nil {
+		return "", err
+	}
+	resp, err := client.Do(req)
+	if err != nil {
+		return "", fmt.Errorf("download %s: %w", artifact.Archive, err)
+	}
+	defer resp.Body.Close()
+	if resp.StatusCode != http.StatusOK {
+		_, _ = io.CopyN(io.Discard, resp.Body, 4096)
+		return "", fmt.Errorf("download %s: unexpected HTTP status %s", artifact.Archive, resp.Status)
+	}
+	if resp.ContentLength > maxSize {
+		return "", fmt.Errorf("download %s exceeds maximum archive size %d bytes (content length %d)", artifact.Archive, maxSize, resp.ContentLength)
+	}
+
+	tmp, err := os.CreateTemp(filepath.Dir(path), "."+artifact.Archive+"-*")
+	if err != nil {
+		return "", err
+	}
+	tmpName := tmp.Name()
+	published := false
+	defer func() {
+		_ = tmp.Close()
+		if !published {
+			_ = os.Remove(tmpName)
+		}
+	}()
+	h := sha256.New()
+	written, err := io.Copy(io.MultiWriter(tmp, h), io.LimitReader(resp.Body, maxSize+1))
+	if err != nil {
+		return "", fmt.Errorf("download %s body: %w", artifact.Archive, err)
+	}
+	if written > maxSize {
+		return "", fmt.Errorf("download %s exceeds maximum archive size %d bytes", artifact.Archive, maxSize)
+	}
+	actual = hex.EncodeToString(h.Sum(nil))
+	if !strings.EqualFold(actual, artifact.SHA256) {
+		return "", fmt.Errorf("download %s checksum mismatch: expected %s, got %s", artifact.Archive, artifact.SHA256, actual)
+	}
+	if err := tmp.Sync(); err != nil {
+		return "", err
+	}
+	if err := tmp.Close(); err != nil {
+		return "", err
+	}
+	if err := os.Rename(tmpName, path); err != nil {
+		// A concurrent writer may have published the same valid archive.
+		if valid, _, checkErr := validSHA256(path, artifact.SHA256); checkErr == nil && valid {
+			return path, nil
+		}
+		return "", fmt.Errorf("publish %s: %w", path, err)
+	}
+	published = true
+	if valid, actual, err := validSHA256(path, artifact.SHA256); err != nil || !valid {
+		_ = os.Remove(path)
+		return "", fmt.Errorf("validate published archive %s: expected %s, got %s: %v", path, artifact.SHA256, actual, err)
+	}
+	return path, nil
+}
+
+func validSHA256(path, expected string) (bool, string, error) {
+	f, err := os.Open(path)
+	if err != nil {
+		return false, "", err
+	}
+	defer f.Close()
+	h := sha256.New()
+	if _, err := io.Copy(h, f); err != nil {
+		return false, "", err
+	}
+	actual := hex.EncodeToString(h.Sum(nil))
+	return strings.EqualFold(actual, expected), actual, nil
+}
+
+func printableHash(hash string) string {
+	if hash == "" {
+		return "missing"
+	}
+	return hash
+}
+
+func downloadClient() *http.Client { return &http.Client{Timeout: 2 * time.Minute} }
diff --git a/core/auth/ui/e2e/artifacts_test.go b/core/auth/ui/e2e/artifacts_test.go
new file mode 100644
index 0000000..89c8d77
--- /dev/null
+++ b/core/auth/ui/e2e/artifacts_test.go
@@ -0,0 +1,282 @@
+package e2e
+
+import (
+	"context"
+	"crypto/sha256"
+	"encoding/hex"
+	"io"
+	"net/http"
+	"net/http/httptest"
+	"os"
+	"path/filepath"
+	"strings"
+	"sync/atomic"
+	"testing"
+	"time"
+)
+
+func TestArtifactPlatforms(t *testing.T) {
+	if len(artifactPlatforms) != 4 {
+		t.Fatalf("platform count=%d, want 4", len(artifactPlatforms))
+	}
+	for _, target := range []string{"linux/amd64", "linux/arm64", "darwin/amd64", "darwin/arm64"} {
+		parts := strings.Split(target, "/")
+		artifacts, err := artifactsFor(parts[0], parts[1])
+		if err != nil {
+			t.Fatal(err)
+		}
+		for _, artifact := range []releaseArtifact{artifacts.Kratos, artifacts.Hydra} {
+			if len(artifact.SHA256) != 64 {
+				t.Errorf("%s has invalid hash %q", artifact.Archive, artifact.SHA256)
+			}
+			if !strings.Contains(artifact.URL, artifact.Version) || !strings.HasSuffix(artifact.URL, artifact.Archive) {
+				t.Errorf("invalid release URL %q", artifact.URL)
+			}
+		}
+	}
+	for _, target := range [][2]string{{"windows", "amd64"}, {"linux", "386"}, {"plan9", "amd64"}, {"darwin", "386"}} {
+		if _, err := artifactsFor(target[0], target[1]); err == nil || !strings.Contains(err.Error(), "unsupported E2E platform") {
+			t.Errorf("artifactsFor(%q,%q) error=%v", target[0], target[1], err)
+		}
+	}
+}
+
+func TestOfficialArtifactHashes(t *testing.T) {
+	want := map[string]string{
+		"kratos_1.1.0-linux_sqlite_64bit.tar.gz": "6fb3077252dde7578c3100d2cd4eb52364ca6b3c1b0b76987e6d586e29008cbd",
+		"kratos_1.1.0-linux_sqlite_arm64.tar.gz": "fde8a1a1aebd153baff88b1232e0c2a34fdaaafe90b5364f4ea580151e74898e",
+		"kratos_1.1.0-macOS_sqlite_64bit.tar.gz": "ebdc94f27cb6e6a3087ed756accfb7837465ac8e30af9433b4414101814f7769",
+		"kratos_1.1.0-macOS_sqlite_arm64.tar.gz": "6681d7b15dd04686d10764750ce3ad69672b3962553223399a3a315ba5370517",
+		"hydra_2.2.0-linux_sqlite_64bit.tar.gz":  "0fe0539fa452496ac5d98b558f93eb2dbb4cf43733da0b09f8f2bdb4445fc31e",
+		"hydra_2.2.0-linux_sqlite_arm64.tar.gz":  "c499ffdaae0f2ab85eff0567214734515b741a393bef89115c16018f4dc0560d",
+		"hydra_2.2.0-macOS_sqlite_64bit.tar.gz":  "3d40ca8e99e2a6d840130928d5e0245212dba0eea9c26a0d7186ebb4382e673d",
+		"hydra_2.2.0-macOS_sqlite_arm64.tar.gz":  "89732ad1494c57ea39348f62dc5ef5c48de129cd205b17cb12bb67ad27094bb7",
+	}
+	for _, platform := range artifactPlatforms {
+		for _, artifact := range []releaseArtifact{platform.Kratos, platform.Hydra} {
+			if want[artifact.Archive] != artifact.SHA256 {
+				t.Errorf("hash for %s=%s", artifact.Archive, artifact.SHA256)
+			}
+		}
+	}
+}
+
+func TestEnsureArchiveDownloadAndCache(t *testing.T) {
+	body := []byte("official archive bytes")
+	hash := sha256.Sum256(body)
+	var requests atomic.Int32
+	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
+		requests.Add(1)
+		_, _ = w.Write(body)
+	}))
+	defer server.Close()
+	artifact := releaseArtifact{"kratos", "v1", "archive.tar.gz", hex.EncodeToString(hash[:]), server.URL}
+	root := t.TempDir()
+	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
+	defer cancel()
+	path, err := ensureArchive(ctx, server.Client(), root, artifact, false)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if got, _ := os.ReadFile(path); string(got) != string(body) {
+		t.Fatalf("cached body=%q", got)
+	}
+	if _, err := ensureArchive(ctx, server.Client(), root, artifact, false); err != nil {
+		t.Fatal(err)
+	}
+	if requests.Load() != 1 {
+		t.Fatalf("requests=%d, want 1 valid cache hit", requests.Load())
+	}
+}
+
+func TestEnsureArchiveReplacesInvalidCache(t *testing.T) {
+	body := []byte("valid")
+	hash := sha256.Sum256(body)
+	var requests atomic.Int32
+	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { requests.Add(1); _, _ = w.Write(body) }))
+	defer server.Close()
+	artifact := releaseArtifact{"hydra", "v2", "archive.tar.gz", hex.EncodeToString(hash[:]), server.URL}
+	root := t.TempDir()
+	path := archiveCachePath(root, artifact)
+	if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
+		t.Fatal(err)
+	}
+	if err := os.WriteFile(path, []byte("invalid"), 0o600); err != nil {
+		t.Fatal(err)
+	}
+	if _, err := ensureArchive(context.Background(), server.Client(), root, artifact, false); err != nil {
+		t.Fatal(err)
+	}
+	if requests.Load() != 1 {
+		t.Fatalf("requests=%d", requests.Load())
+	}
+}
+
+func TestEnsureArchiveFailures(t *testing.T) {
+	body := []byte("complete")
+	hash := sha256.Sum256(body)
+	tests := []struct {
+		name    string
+		handler http.HandlerFunc
+		want    string
+	}{
+		{"non-200", func(w http.ResponseWriter, _ *http.Request) { http.Error(w, "no", http.StatusBadGateway) }, "unexpected HTTP status"},
+		{"checksum", func(w http.ResponseWriter, _ *http.Request) { _, _ = w.Write([]byte("wrong")) }, "checksum mismatch"},
+		{"truncated", func(w http.ResponseWriter, _ *http.Request) {
+			w.Header().Set("Content-Length", "100")
+			_, _ = w.Write(body[:2])
+		}, "body"},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			server := httptest.NewServer(tt.handler)
+			defer server.Close()
+			artifact := releaseArtifact{"kratos", "v1", "a.tar.gz", hex.EncodeToString(hash[:]), server.URL}
+			root := t.TempDir()
+			path := archiveCachePath(root, artifact)
+			_, err := ensureArchive(context.Background(), server.Client(), root, artifact, false)
+			if err == nil || !strings.Contains(err.Error(), tt.want) {
+				t.Fatalf("error=%v, want %q", err, tt.want)
+			}
+			if _, statErr := os.Stat(path); !os.IsNotExist(statErr) {
+				t.Fatalf("canonical corrupt cache exists: %v", statErr)
+			}
+		})
+	}
+}
+
+func TestEnsureArchiveRejectsOversizedResponse(t *testing.T) {
+	body := strings.Repeat("x", 33)
+	hash := sha256.Sum256([]byte(body))
+	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
+		w.(http.Flusher).Flush() // Force a chunked response so the stream limit is exercised.
+		_, _ = io.WriteString(w, body)
+	}))
+	defer server.Close()
+	artifact := releaseArtifact{"kratos", "v1", "oversized.tar.gz", hex.EncodeToString(hash[:]), server.URL}
+	root := t.TempDir()
+	_, err := ensureArchiveWithLimit(context.Background(), server.Client(), root, artifact, false, 32)
+	if err == nil || !strings.Contains(err.Error(), "exceeds maximum archive size 32 bytes") {
+		t.Fatalf("oversized response error=%v", err)
+	}
+	if _, err := os.Stat(archiveCachePath(root, artifact)); !os.IsNotExist(err) {
+		t.Fatalf("oversized response published canonical cache: %v", err)
+	}
+	temps, err := filepath.Glob(filepath.Join(filepath.Dir(archiveCachePath(root, artifact)), ".oversized.tar.gz-*"))
+	if err != nil || len(temps) != 0 {
+		t.Fatalf("oversized response left temporary files %v: %v", temps, err)
+	}
+}
+
+func TestEnsureArchiveConcurrentInvalidReplacementUsesPublishedWinner(t *testing.T) {
+	body := []byte("valid concurrent archive")
+	hash := sha256.Sum256(body)
+	var requests atomic.Int32
+	started := make(chan struct{})
+	release := make(chan struct{})
+	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
+		if requests.Add(1) == 1 {
+			close(started)
+			<-release
+		}
+		_, _ = w.Write(body)
+	}))
+	defer server.Close()
+	artifact := releaseArtifact{"hydra", "v2", "concurrent.tar.gz", hex.EncodeToString(hash[:]), server.URL}
+	root := t.TempDir()
+	path := archiveCachePath(root, artifact)
+	if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
+		t.Fatal(err)
+	}
+	if err := os.WriteFile(path, []byte("invalid"), 0o600); err != nil {
+		t.Fatal(err)
+	}
+	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
+	defer cancel()
+	results := make(chan error, 2)
+	go func() { _, err := ensureArchive(ctx, server.Client(), root, artifact, false); results <- err }()
+	select {
+	case <-started:
+	case <-ctx.Done():
+		t.Fatal("first download did not start")
+	}
+	go func() { _, err := ensureArchive(ctx, server.Client(), root, artifact, false); results <- err }()
+	time.Sleep(100 * time.Millisecond)
+	if got := requests.Load(); got != 1 {
+		close(release)
+		t.Fatalf("concurrent waiter bypassed cache lock: requests=%d", got)
+	}
+	close(release)
+	for range 2 {
+		if err := <-results; err != nil {
+			t.Fatal(err)
+		}
+	}
+	if got := requests.Load(); got != 1 {
+		t.Fatalf("published archive was downloaded again: requests=%d", got)
+	}
+	if valid, _, err := validSHA256(path, artifact.SHA256); err != nil || !valid {
+		t.Fatalf("concurrent replacement invalid: valid=%v error=%v", valid, err)
+	}
+}
+
+func TestEnsureArchiveOfflineInvalid(t *testing.T) {
+	artifact := releaseArtifact{"kratos", "v1", "a.tar.gz", strings.Repeat("a", 64), "http://invalid.example"}
+	root := t.TempDir()
+	path := archiveCachePath(root, artifact)
+	if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
+		t.Fatal(err)
+	}
+	if err := os.WriteFile(path, []byte("bad"), 0o600); err != nil {
+		t.Fatal(err)
+	}
+	_, err := ensureArchive(context.Background(), &http.Client{}, root, artifact, true)
+	if err == nil || !strings.Contains(err.Error(), path) || !strings.Contains(err.Error(), artifact.SHA256) {
+		t.Fatalf("error=%v", err)
+	}
+}
+
+func TestCacheRootDefaultAndOverride(t *testing.T) {
+	t.Setenv("AUTH_UI_E2E_CACHE_DIR", "")
+	if got := cacheRoot("/repo"); got != filepath.Join("/repo", "e2e", "cache") {
+		t.Fatalf("default cache root=%q", got)
+	}
+	t.Setenv("AUTH_UI_E2E_CACHE_DIR", "/override")
+	if got := cacheRoot("/repo"); got != "/override" {
+		t.Fatalf("override cache root=%q", got)
+	}
+}
+
+func TestRepositoryAndInstallerVersions(t *testing.T) {
+	repo, err := repositoryDir()
+	if err != nil {
+		t.Fatal(err)
+	}
+	old, err := os.Getwd()
+	if err != nil {
+		t.Fatal(err)
+	}
+	if err := os.Chdir(t.TempDir()); err != nil {
+		t.Fatal(err)
+	}
+	defer os.Chdir(old)
+	if again, err := repositoryDir(); err != nil || again != repo {
+		t.Fatalf("repositoryDir=%q err=%v", again, err)
+	}
+	module, err := os.ReadFile(filepath.Join(repo, "go.mod"))
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !strings.Contains(string(module), "go 1.22") {
+		t.Error("go.mod does not set go 1.22")
+	}
+	if !strings.Contains(string(module), "github.com/mxschmitt/playwright-go "+playwrightVersion) {
+		t.Errorf("go.mod does not pin Playwright %s", playwrightVersion)
+	}
+	if strings.Contains(string(module), "github.com/playwright-community/playwright-go") {
+		t.Error("go.mod retains retired Playwright binding")
+	}
+	if playwrightCLIVersion != "1.61.1" || chromiumRevision != "1228" || chromiumVersion != "149.0.7827.55" || ffmpegRevision != "1011" {
+		t.Fatalf("unexpected embedded runtime contract: CLI=%s Chromium=%s/%s FFmpeg=%s", playwrightCLIVersion, chromiumRevision, chromiumVersion, ffmpegRevision)
+	}
+}
diff --git a/core/auth/ui/e2e/browser.go b/core/auth/ui/e2e/browser.go
new file mode 100644
index 0000000..19949f5
--- /dev/null
+++ b/core/auth/ui/e2e/browser.go
@@ -0,0 +1,444 @@
+package e2e
+
+import (
+	"encoding/json"
+	"fmt"
+	"net/url"
+	"os"
+	"path/filepath"
+	"regexp"
+	"sort"
+	"strings"
+	"sync"
+	"time"
+
+	playwright "github.com/mxschmitt/playwright-go"
+)
+
+type browserRuntime struct {
+	Playwright *playwright.Playwright
+	Browser    playwright.Browser
+	mu         sync.Mutex
+	closed     bool
+}
+
+func startBrowserRuntime() (*browserRuntime, error) {
+	return startBrowserRuntimeOwned(nil)
+}
+
+func startBrowserRuntimeOwned(owner *suiteLifecycle) (*browserRuntime, error) {
+	runtime := &browserRuntime{}
+	if owner != nil && !owner.setBrowser(runtime) {
+		return nil, fmt.Errorf("E2E watchdog fired before browser ownership registration")
+	}
+	pw, err := playwright.Run()
+	if err != nil {
+		return runtime, fmt.Errorf("start Playwright %s: %w; run `make install-e2e-browser` (go run github.com/mxschmitt/playwright-go/cmd/playwright@%s install chromium)", playwrightVersion, err, playwrightVersion)
+	}
+	runtime.mu.Lock()
+	if runtime.closed {
+		runtime.mu.Unlock()
+		_ = pw.Stop()
+		return runtime, fmt.Errorf("E2E cleanup started while launching Playwright")
+	}
+	runtime.Playwright = pw
+	runtime.mu.Unlock()
+	browser, err := pw.Chromium.Launch(playwright.BrowserTypeLaunchOptions{Headless: playwright.Bool(true)})
+	if err != nil {
+		_ = runtime.Close()
+		return runtime, fmt.Errorf("launch Playwright-managed Chromium: %w; run `make install-e2e-browser`", err)
+	}
+	runtime.mu.Lock()
+	if runtime.closed {
+		runtime.mu.Unlock()
+		_ = browser.Close()
+		return runtime, fmt.Errorf("E2E cleanup started while launching Chromium")
+	}
+	runtime.Browser = browser
+	runtime.mu.Unlock()
+	if got := browser.Version(); got != chromiumVersion {
+		_ = runtime.Close()
+		return runtime, fmt.Errorf("unexpected managed Chromium version %q, want %s (revision %s, Playwright CLI %s)", got, chromiumVersion, chromiumRevision, playwrightCLIVersion)
+	}
+	return runtime, nil
+}
+
+func (r *browserRuntime) Close() error {
+	if r == nil {
+		return nil
+	}
+	r.mu.Lock()
+	if r.closed {
+		r.mu.Unlock()
+		return nil
+	}
+	r.closed = true
+	browser, pw := r.Browser, r.Playwright
+	r.mu.Unlock()
+	var errs []string
+	if browser != nil {
+		if err := browser.Close(); err != nil {
+			errs = append(errs, err.Error())
+		}
+	}
+	if pw != nil {
+		if err := pw.Stop(); err != nil {
+			errs = append(errs, err.Error())
+		}
+	}
+	if len(errs) > 0 {
+		return fmt.Errorf("close browser runtime: %s", strings.Join(errs, "; "))
+	}
+	return nil
+}
+
+type testReporter interface {
+	Name() string
+	Failed() bool
+	Errorf(string, ...any)
+	Cleanup(func())
+}
+
+type browserSession struct {
+	Page           playwright.Page
+	Context        playwright.BrowserContext
+	t              testReporter
+	dir            string
+	video          playwright.Video
+	started        time.Time
+	screenshots    []string
+	checkpoint     int
+	finalize       sync.Once
+	lifecycleMu    sync.Mutex
+	forcedFailure  bool
+	registry       *sessionRegistry
+	browserVer     string
+	blockedMu      sync.Mutex
+	blocked        []string
+	requestsMu     sync.Mutex
+	requests       []requestMetadata
+	tracingStarted bool
+	screenshotOp   func(string) error
+	stopTraceOp    func(string) error
+	closeContextOp func() error
+	saveVideoOp    func(string) error
+	finalURLOp     func() string
+}
+
+func newBrowserSession(t testReporter, browser playwright.Browser, root string, allowedOrigins []string) (*browserSession, error) {
+	session, err := newBrowserSessionOwner(t, root, browser.Version())
+	if err != nil {
+		return nil, err
+	}
+	// Register while holding the construction/finalization lock. A watchdog
+	// either snapshots this ownership and waits here, or rejects construction
+	// before any external Playwright context exists.
+	session.lifecycleMu.Lock()
+	if activeSuiteLifecycle != nil {
+		session.registry = activeSuiteLifecycle.sessions
+		if !session.registry.add(session) {
+			session.lifecycleMu.Unlock()
+			_ = session.finalizeAfterTimeout()
+			return nil, fmt.Errorf("create browser session after E2E watchdog cleanup started")
+		}
+	}
+	defer session.lifecycleMu.Unlock()
+	videoDir := filepath.Join(session.dir, ".video")
+	context, err := browser.NewContext(playwright.BrowserNewContextOptions{
+		Viewport:       &playwright.Size{Width: 1280, Height: 720},
+		RecordVideo:    &playwright.RecordVideo{Dir: playwright.String(videoDir), Size: &playwright.Size{Width: 1280, Height: 720}},
+		ServiceWorkers: playwright.ServiceWorkerPolicyBlock,
+	})
+	if err != nil {
+		return nil, err
+	}
+	session.Context = context
+	if err := context.Tracing().Start(playwright.TracingStartOptions{Screenshots: playwright.Bool(true), Snapshots: playwright.Bool(true), Sources: playwright.Bool(true)}); err != nil {
+		return nil, err
+	}
+	session.tracingStarted = true
+	page, err := context.NewPage()
+	if err != nil {
+		return nil, err
+	}
+	page.SetDefaultTimeout(15_000)
+	page.SetDefaultNavigationTimeout(30_000)
+	page.OnRequest(func(request playwright.Request) {
+		session.recordRequest(request.Method(), 0, request.URL())
+	})
+	page.OnResponse(func(response playwright.Response) {
+		session.recordRequest(response.Request().Method(), response.Status(), response.Request().URL())
+	})
+	s := session
+	s.Page = page
+	s.video = page.Video()
+	policy := newRoutePolicy(allowedOrigins)
+	if err := context.Route("**/*", func(route playwright.Route) {
+		if policy(route.Request().URL()) {
+			_ = route.Continue()
+		} else {
+			session.recordBlocked(route.Request().URL())
+			_ = route.Abort("blockedbyclient")
+		}
+	}); err != nil {
+		return nil, err
+	}
+	if err := s.screenshot("00-initial.png"); err != nil {
+		return nil, err
+	}
+	return s, nil
+}
+
+func newBrowserSessionOwner(t testReporter, root, browserVersion string) (*browserSession, error) {
+	dir := filepath.Join(root, sanitizeName(t.Name()))
+	if err := os.MkdirAll(filepath.Join(dir, "screenshots"), 0o700); err != nil {
+		return nil, err
+	}
+	if err := os.MkdirAll(filepath.Join(dir, ".video"), 0o700); err != nil {
+		return nil, err
+	}
+	session := &browserSession{t: t, dir: dir, started: time.Now().UTC(), browserVer: browserVersion}
+	session.installDefaultArtifactOps()
+	// Own metadata and all available partial artifacts before Playwright context
+	// construction. If Playwright cannot create a context/page/trace, cleanup
+	// records the failure without pretending the unavailable artifacts succeeded.
+	t.Cleanup(func() {
+		if err := session.Finalize(); err != nil {
+			t.Errorf("finalize browser artifacts: %v", err)
+		}
+	})
+	return session, nil
+}
+
+func newRoutePolicy(allowedOrigins []string) func(string) bool {
+	allowed := make(map[string]struct{}, len(allowedOrigins))
+	for _, origin := range allowedOrigins {
+		u, err := url.Parse(origin)
+		if err == nil && u.Scheme == "http" && u.Hostname() == "127.0.0.1" && u.Port() != "" && u.Path == "" {
+			allowed[u.Scheme+"://"+u.Host] = struct{}{}
+		}
+	}
+	return func(raw string) bool {
+		u, err := url.Parse(raw)
+		if err != nil || u.Scheme != "http" || u.Hostname() != "127.0.0.1" || u.Port() == "" || u.User != nil {
+			return false
+		}
+		_, ok := allowed[u.Scheme+"://"+u.Host]
+		return ok
+	}
+}
+
+type requestMetadata struct {
+	Method string `json:"method"`
+	Status int    `json:"status,omitempty"`
+	Origin string `json:"origin"`
+	Path   string `json:"path"`
+}
+
+func sanitizedRequest(method string, status int, raw string) (requestMetadata, bool) {
+	u, err := url.Parse(raw)
+	if err != nil || u.Scheme == "" || u.Host == "" {
+		return requestMetadata{}, false
+	}
+	return requestMetadata{Method: method, Status: status, Origin: u.Scheme + "://" + u.Host, Path: u.EscapedPath()}, true
+}
+
+func (s *browserSession) recordRequest(method string, status int, raw string) {
+	metadata, ok := sanitizedRequest(method, status, raw)
+	if !ok {
+		return
+	}
+	s.requestsMu.Lock()
+	s.requests = append(s.requests, metadata)
+	s.requestsMu.Unlock()
+}
+
+func (s *browserSession) RequestMetadata() []requestMetadata {
+	s.requestsMu.Lock()
+	defer s.requestsMu.Unlock()
+	return append([]requestMetadata(nil), s.requests...)
+}
+
+func (s *browserSession) recordBlocked(raw string) {
+	u, err := url.Parse(raw)
+	if err != nil {
+		return
+	}
+	s.blockedMu.Lock()
+	s.blocked = append(s.blocked, u.Scheme+"://"+u.Host+u.Path)
+	s.blockedMu.Unlock()
+}
+
+func (s *browserSession) BlockedRequests() []string {
+	s.blockedMu.Lock()
+	defer s.blockedMu.Unlock()
+	return sortedStrings(s.blocked)
+}
+
+func (s *browserSession) Checkpoint(name string) error {
+	s.lifecycleMu.Lock()
+	defer s.lifecycleMu.Unlock()
+	s.checkpoint++
+	return s.screenshot(fmt.Sprintf("%02d-%s.png", s.checkpoint, sanitizeName(name)))
+}
+
+func (s *browserSession) installDefaultArtifactOps() {
+	s.screenshotOp = func(path string) error {
+		if s.Page == nil {
+			return fmt.Errorf("page unavailable")
+		}
+		_, err := s.Page.Screenshot(playwright.PageScreenshotOptions{Path: playwright.String(path), FullPage: playwright.Bool(true)})
+		return err
+	}
+	s.stopTraceOp = func(path string) error {
+		if s.Context == nil || !s.tracingStarted {
+			return fmt.Errorf("tracing unavailable")
+		}
+		return s.Context.Tracing().Stop(path)
+	}
+	s.closeContextOp = func() error {
+		if s.Context == nil {
+			return nil
+		}
+		return s.Context.Close()
+	}
+	s.saveVideoOp = func(path string) error {
+		if s.video == nil {
+			return fmt.Errorf("video unavailable")
+		}
+		return s.video.SaveAs(path)
+	}
+	s.finalURLOp = func() string {
+		if s.Page == nil {
+			return ""
+		}
+		return s.Page.URL()
+	}
+}
+
+func (s *browserSession) screenshot(name string) error {
+	path := filepath.Join(s.dir, "screenshots", name)
+	if err := s.screenshotOp(path); err != nil {
+		return err
+	}
+	s.screenshots = append(s.screenshots, name)
+	return nil
+}
+
+func (s *browserSession) Finalize() error {
+	if s.registry != nil {
+		return s.registry.finalizeNormal(s)
+	}
+	return s.finalizeClaimed(false)
+}
+
+func (s *browserSession) finalizeAfterTimeout() error {
+	return s.finalizeClaimed(true)
+}
+
+func (s *browserSession) finalizeClaimed(forcedFailure bool) error {
+	s.lifecycleMu.Lock()
+	defer s.lifecycleMu.Unlock()
+	if forcedFailure {
+		s.forcedFailure = true
+	}
+	var finalErr error
+	s.finalize.Do(func() {
+		var errs []string
+		if err := s.screenshot("99-final.png"); err != nil {
+			errs = append(errs, "final screenshot: "+err.Error())
+		}
+		if s.t.Failed() || s.forcedFailure {
+			if err := s.screenshot("failure.png"); err != nil {
+				errs = append(errs, "failure screenshot: "+err.Error())
+			}
+		}
+		if err := s.stopTraceOp(filepath.Join(s.dir, "trace.zip")); err != nil {
+			errs = append(errs, "trace: "+err.Error())
+		}
+		finalURL := sanitizeFinalURL(s.finalURLOp())
+		if err := s.closeContextOp(); err != nil {
+			errs = append(errs, "context: "+err.Error())
+		}
+		if err := s.saveVideoOp(filepath.Join(s.dir, "video.webm")); err != nil {
+			errs = append(errs, "video: "+err.Error())
+		} else {
+			_ = os.RemoveAll(filepath.Join(s.dir, ".video"))
+		}
+		outcome := "passed"
+		if s.t.Failed() || s.forcedFailure || len(errs) > 0 {
+			outcome = "failed"
+		}
+		metadata := sessionMetadata{TestName: s.t.Name(), StartedAt: s.started, FinishedAt: time.Now().UTC(), Outcome: outcome, BindingVersion: playwrightVersion, CLIVersion: playwrightCLIVersion, ChromiumRevision: chromiumRevision, BrowserVersion: s.browserVer, Screenshots: s.screenshots, FinalURL: finalURL}
+		data, err := json.MarshalIndent(metadata, "", "  ")
+		if err == nil {
+			err = os.WriteFile(filepath.Join(s.dir, "session.json"), append(data, '\n'), 0o600)
+		}
+		if err != nil {
+			errs = append(errs, "metadata: "+err.Error())
+		}
+		if len(errs) > 0 {
+			finalErr = fmt.Errorf("%s", strings.Join(errs, "; "))
+		}
+	})
+	return finalErr
+}
+
+func artifactOutcomeExpectation(failedBeforeFinalize, failedAfterFinalize bool) (outcome string, requireFailureScreenshot bool) {
+	if failedBeforeFinalize {
+		return "failed", true
+	}
+	if failedAfterFinalize {
+		return "failed", false
+	}
+	return "passed", false
+}
+
+const expectedExternalFontRequest = "https://cdnjs.cloudflare.com/ajax/libs/hack-font/3.3.0/web/hack.min.css"
+
+func isExpectedBlockedBrowserRequest(request string) bool {
+	return request == expectedExternalFontRequest
+}
+
+type sessionMetadata struct {
+	TestName         string    `json:"test_name"`
+	StartedAt        time.Time `json:"started_at"`
+	FinishedAt       time.Time `json:"finished_at"`
+	Outcome          string    `json:"outcome"`
+	BindingVersion   string    `json:"binding_version"`
+	CLIVersion       string    `json:"playwright_cli_version"`
+	ChromiumRevision string    `json:"chromium_revision"`
+	BrowserVersion   string    `json:"browser_version"`
+	Screenshots      []string  `json:"screenshots"`
+	FinalURL         string    `json:"final_url"`
+}
+
+var unsafeName = regexp.MustCompile(`[^A-Za-z0-9._-]+`)
+
+func sanitizeName(name string) string {
+	name = strings.Trim(unsafeName.ReplaceAllString(name, "-"), "-.")
+	if name == "" {
+		return "unnamed"
+	}
+	if len(name) > 100 {
+		name = name[:100]
+	}
+	return name
+}
+
+func sanitizeFinalURL(raw string) string {
+	u, err := url.Parse(raw)
+	if err != nil || u.Scheme == "" || u.Host == "" {
+		return ""
+	}
+	u.RawQuery = ""
+	u.Fragment = ""
+	u.User = nil
+	return u.String()
+}
+
+func sortedStrings(values []string) []string {
+	out := append([]string(nil), values...)
+	sort.Strings(out)
+	return out
+}
diff --git a/core/auth/ui/e2e/browser_artifacts_test.go b/core/auth/ui/e2e/browser_artifacts_test.go
new file mode 100644
index 0000000..5825dcf
--- /dev/null
+++ b/core/auth/ui/e2e/browser_artifacts_test.go
@@ -0,0 +1,144 @@
+//go:build e2e
+
+package e2e
+
+import (
+	"archive/zip"
+	"bytes"
+	"encoding/json"
+	"fmt"
+	"os"
+	"path/filepath"
+	"strings"
+	"testing"
+)
+
+func TestPinnedStackReady(t *testing.T) {
+	if testStack == nil || testBrowser == nil {
+		t.Fatal("suite was not initialized")
+	}
+	dir := filepath.Join(testStack.ArtifactDir, sanitizeName(t.Name()))
+	failedBeforeFinalize := false
+	t.Cleanup(func() { assertArtifactSet(t, dir, failedBeforeFinalize) })
+	session, err := newBrowserSession(t, testBrowser.Browser, testStack.ArtifactDir, testStack.allowedOrigins())
+	if err != nil {
+		t.Fatal(err)
+	}
+	t.Cleanup(func() { failedBeforeFinalize = t.Failed() })
+
+	for name, process := range map[string]*supervisedProcess{"kratos": testStack.Kratos, "hydra": testStack.Hydra, "auth-ui": testStack.AuthUI} {
+		if !process.alive() {
+			t.Fatalf("%s process is not alive", name)
+		}
+	}
+	for _, endpoint := range []string{testStack.KratosURL + "/health/ready", testStack.KratosAdmin + "/health/ready", testStack.HydraURL + "/health/ready", testStack.HydraAdmin + "/health/ready"} {
+		if err := testStack.healthy(endpoint); err != nil {
+			t.Fatalf("health check %s: %v", sanitizeFinalURL(endpoint), err)
+		}
+	}
+	if kratosVersion != "v1.1.0" || hydraVersion != "v2.2.0" || playwrightVersion != "v0.6100.0" {
+		t.Fatalf("unexpected pinned versions: %s %s %s", kratosVersion, hydraVersion, playwrightVersion)
+	}
+	if got := testBrowser.Browser.Version(); got != chromiumVersion {
+		t.Fatalf("Chromium version=%q, want %s revision %s", got, chromiumVersion, chromiumRevision)
+	}
+	listenerLogs := map[string][]int{
+		"kratos": {testStack.Ports.KratosPublic, testStack.Ports.KratosAdmin},
+		"hydra":  {testStack.Ports.HydraPublic, testStack.Ports.HydraAdmin},
+	}
+	for service, ports := range listenerLogs {
+		log, err := os.ReadFile(testStack.logPath(service))
+		if err != nil {
+			t.Fatal(err)
+		}
+		if strings.Contains(string(log), "0.0.0.0:") {
+			t.Fatalf("%s reported a wildcard listener", service)
+		}
+		for _, port := range ports {
+			if !strings.Contains(string(log), fmt.Sprintf("http server on 127.0.0.1:%d", port)) && !strings.Contains(string(log), fmt.Sprintf("httpd on: 127.0.0.1:%d", port)) {
+				t.Fatalf("%s did not report loopback listener port %d", service, port)
+			}
+		}
+	}
+
+	if _, err := session.Page.Goto(testStack.UIURL + "/login"); err != nil {
+		t.Fatal(err)
+	}
+	for _, selector := range []string{`input[name="username"]`, `input[name="password"]`} {
+		visible, err := session.Page.Locator(selector).IsVisible()
+		if err != nil || !visible {
+			t.Fatalf("login field %s visible=%v err=%v", selector, visible, err)
+		}
+	}
+	if err := session.screenshot("00-login.png"); err != nil {
+		t.Fatal(err)
+	}
+	blocked := session.BlockedRequests()
+	foundCDN := false
+	for _, request := range blocked {
+		if strings.HasPrefix(request, "https://cdnjs.cloudflare.com/") {
+			foundCDN = true
+		}
+	}
+	if !foundCDN {
+		t.Fatalf("expected external CDN font request to be aborted, blocked=%v", blocked)
+	}
+	policy := newRoutePolicy(testStack.allowedOrigins())
+	for _, request := range session.RequestMetadata() {
+		if request.Status > 0 && !policy(request.Origin+request.Path) {
+			t.Fatalf("unowned request received a response: %+v", request)
+		}
+	}
+}
+
+func TestBrowserArtifactFinalization(t *testing.T) {
+	dir := filepath.Join(testStack.ArtifactDir, sanitizeName(t.Name()))
+	failedBeforeFinalize := false
+	t.Cleanup(func() { assertArtifactSet(t, dir, failedBeforeFinalize) })
+	session, err := newBrowserSession(t, testBrowser.Browser, testStack.ArtifactDir, testStack.allowedOrigins())
+	if err != nil {
+		t.Fatal(err)
+	}
+	t.Cleanup(func() { failedBeforeFinalize = t.Failed() })
+	if _, err := session.Page.Goto(testStack.UIURL + "/login"); err != nil {
+		t.Fatal(err)
+	}
+	if err := session.Checkpoint("login-rendered"); err != nil {
+		t.Fatal(err)
+	}
+}
+
+func assertArtifactSet(t *testing.T, dir string, failedBeforeFinalize bool) {
+	t.Helper()
+	wantOutcome, requireFailureScreenshot := artifactOutcomeExpectation(failedBeforeFinalize, t.Failed())
+	required := []string{"screenshots/00-initial.png", "screenshots/99-final.png", "video.webm", "trace.zip", "session.json"}
+	if requireFailureScreenshot {
+		required = append(required, "screenshots/failure.png")
+	}
+	for _, path := range required {
+		info, err := os.Stat(filepath.Join(dir, path))
+		if err != nil || info.Size() == 0 {
+			t.Fatalf("artifact %s missing or empty: info=%v err=%v", path, info, err)
+		}
+	}
+	png, err := os.ReadFile(filepath.Join(dir, "screenshots", "99-final.png"))
+	if err != nil || !bytes.HasPrefix(png, []byte("\x89PNG\r\n\x1a\n")) {
+		t.Fatalf("final screenshot is not PNG: %v", err)
+	}
+	zr, err := zip.OpenReader(filepath.Join(dir, "trace.zip"))
+	if err != nil {
+		t.Fatalf("trace is not a valid ZIP: %v", err)
+	}
+	if len(zr.File) == 0 {
+		t.Error("trace ZIP is empty")
+	}
+	_ = zr.Close()
+	data, err := os.ReadFile(filepath.Join(dir, "session.json"))
+	var metadata sessionMetadata
+	if err != nil || json.Unmarshal(data, &metadata) != nil || metadata.Outcome != wantOutcome {
+		t.Fatalf("invalid session metadata: %v: %s", err, data)
+	}
+	if metadata.BindingVersion != playwrightVersion || metadata.CLIVersion != playwrightCLIVersion || metadata.ChromiumRevision != chromiumRevision || metadata.BrowserVersion != chromiumVersion {
+		t.Fatalf("unexpected Playwright metadata: %+v", metadata)
+	}
+}
diff --git a/core/auth/ui/e2e/browser_test.go b/core/auth/ui/e2e/browser_test.go
new file mode 100644
index 0000000..3a42eb3
--- /dev/null
+++ b/core/auth/ui/e2e/browser_test.go
@@ -0,0 +1,251 @@
+package e2e
+
+import (
+	"encoding/json"
+	"fmt"
+	"os"
+	"path/filepath"
+	"strings"
+	"testing"
+	"time"
+)
+
+func TestLoopbackRoutePolicy(t *testing.T) {
+	policy := newRoutePolicy([]string{"http://127.0.0.1:10001", "http://127.0.0.1:10002"})
+	for _, raw := range []string{"http://127.0.0.1:10001/login?flow=secret", "http://127.0.0.1:10002/static/main.css"} {
+		if !policy(raw) {
+			t.Errorf("policy rejected owned URL %q", raw)
+		}
+	}
+	for _, raw := range []string{
+		"https://cdnjs.cloudflare.com/font.css", "http://example.test:10001/", "http://localhost:10001/",
+		"http://127.0.0.1:9999/", "https://127.0.0.1:10001/", "file:///etc/passwd", "data:text/plain,x",
+		"http://user@127.0.0.1:10001/", "not a URL",
+	} {
+		if policy(raw) {
+			t.Errorf("policy allowed unowned URL %q", raw)
+		}
+	}
+}
+
+func TestRoutePolicyRejectsMalformedAllowedOrigins(t *testing.T) {
+	policy := newRoutePolicy([]string{"https://127.0.0.1:1", "http://localhost:2", "http://127.0.0.1/no-port", "garbage"})
+	if policy("http://127.0.0.1:1/") {
+		t.Fatal("malformed allowed origin was accepted")
+	}
+}
+
+func TestBrowserArtifactOutcomeExpectation(t *testing.T) {
+	tests := []struct {
+		name                  string
+		failedBeforeFinalize  bool
+		failedAfterFinalize   bool
+		outcome               string
+		requireFailureCapture bool
+	}{
+		{name: "passed", outcome: "passed"},
+		{name: "behavior failed", failedBeforeFinalize: true, failedAfterFinalize: true, outcome: "failed", requireFailureCapture: true},
+		{name: "finalization failed", failedAfterFinalize: true, outcome: "failed"},
+	}
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			outcome, failure := artifactOutcomeExpectation(test.failedBeforeFinalize, test.failedAfterFinalize)
+			if outcome != test.outcome || failure != test.requireFailureCapture {
+				t.Fatalf("expectation outcome=%q failure=%v", outcome, failure)
+			}
+		})
+	}
+}
+
+func TestExpectedBlockedBrowserRequest(t *testing.T) {
+	if !isExpectedBlockedBrowserRequest(expectedExternalFontRequest) {
+		t.Fatal("known external font request was not recognized")
+	}
+	for _, request := range []string{
+		"https://cdnjs.cloudflare.com/other.css",
+		"https://example.test/unexpected.js",
+		"http://127.0.0.1:1234/unowned",
+		expectedExternalFontRequest + "?token=secret",
+	} {
+		if isExpectedBlockedBrowserRequest(request) {
+			t.Fatalf("unexpected blocked request was accepted: %s", sanitizeFinalURL(request))
+		}
+	}
+}
+
+func TestSanitizedRequestMetadata(t *testing.T) {
+	metadata, ok := sanitizedRequest("GET", 200, "http://127.0.0.1:1234/login?flow=sensitive#fragment")
+	if !ok {
+		t.Fatal("request was not parsed")
+	}
+	if metadata.Method != "GET" || metadata.Status != 200 || metadata.Origin != "http://127.0.0.1:1234" || metadata.Path != "/login" {
+		t.Fatalf("metadata=%+v", metadata)
+	}
+	data, _ := json.Marshal(metadata)
+	if strings.Contains(string(data), "sensitive") || strings.Contains(string(data), "flow") {
+		t.Fatalf("request metadata leaked query: %s", data)
+	}
+	if _, ok := sanitizedRequest("GET", 0, "not a URL"); ok {
+		t.Fatal("invalid URL accepted")
+	}
+}
+
+func TestArtifactNamingAndFailedMetadata(t *testing.T) {
+	if got := sanitizeName("Test Thing/../../secret value"); got != "Test-Thing-..-..-secret-value" {
+		t.Fatalf("sanitized name=%q", got)
+	}
+	if got := sanitizeFinalURL("http://127.0.0.1:1234/login?flow=sensitive#fragment"); got != "http://127.0.0.1:1234/login" {
+		t.Fatalf("sanitized URL=%q", got)
+	}
+	metadata := sessionMetadata{TestName: "TestFailure", StartedAt: time.Unix(1, 0).UTC(), FinishedAt: time.Unix(2, 0).UTC(), Outcome: "failed", BindingVersion: playwrightVersion, CLIVersion: playwrightCLIVersion, ChromiumRevision: chromiumRevision, BrowserVersion: chromiumVersion, Screenshots: []string{"00-initial.png", "99-final.png", "failure.png"}, FinalURL: "http://127.0.0.1:1/login"}
+	data, err := json.Marshal(metadata)
+	if err != nil {
+		t.Fatal(err)
+	}
+	text := string(data)
+	for _, required := range []string{`"outcome":"failed"`, `"failure.png"`, `"binding_version":"v0.6100.0"`, `"playwright_cli_version":"1.61.1"`, `"chromium_revision":"1228"`, `"browser_version":"149.0.7827.55"`} {
+		if !strings.Contains(text, required) {
+			t.Errorf("metadata missing %s: %s", required, text)
+		}
+	}
+	for _, forbidden := range []string{"flow=", "password", "token"} {
+		if strings.Contains(text, forbidden) {
+			t.Errorf("metadata contains forbidden value %q", forbidden)
+		}
+	}
+}
+
+type fakeReporter struct {
+	name     string
+	failed   bool
+	cleanups []func()
+	errors   []string
+}
+
+func (r *fakeReporter) Name() string                 { return r.name }
+func (r *fakeReporter) Failed() bool                 { return r.failed }
+func (r *fakeReporter) Cleanup(fn func())            { r.cleanups = append(r.cleanups, fn) }
+func (r *fakeReporter) Errorf(f string, args ...any) { r.failed = true; r.errors = append(r.errors, f) }
+
+func TestFailedReporterFinalizationWritesFailureArtifacts(t *testing.T) {
+	dir := t.TempDir()
+	reporter := &fakeReporter{name: "TestBehavioralFailure", failed: true}
+	s := &browserSession{t: reporter, dir: dir, started: time.Unix(1, 0).UTC(), browserVer: chromiumVersion}
+	s.screenshotOp = func(path string) error { return os.WriteFile(path, []byte("png"), 0o600) }
+	s.stopTraceOp = func(path string) error { return os.WriteFile(path, []byte("trace"), 0o600) }
+	s.closeContextOp = func() error { return nil }
+	s.saveVideoOp = func(path string) error { return os.WriteFile(path, []byte("video"), 0o600) }
+	s.finalURLOp = func() string { return "http://127.0.0.1:1234/login?flow=secret" }
+	if err := os.MkdirAll(filepath.Join(dir, "screenshots"), 0o700); err != nil {
+		t.Fatal(err)
+	}
+	if err := s.Finalize(); err != nil {
+		t.Fatal(err)
+	}
+	for _, path := range []string{"screenshots/99-final.png", "screenshots/failure.png", "trace.zip", "video.webm", "session.json"} {
+		if _, err := os.Stat(filepath.Join(dir, path)); err != nil {
+			t.Fatalf("required failed artifact %s: %v", path, err)
+		}
+	}
+	data, err := os.ReadFile(filepath.Join(dir, "session.json"))
+	if err != nil {
+		t.Fatal(err)
+	}
+	var metadata sessionMetadata
+	if err := json.Unmarshal(data, &metadata); err != nil {
+		t.Fatal(err)
+	}
+	if metadata.Outcome != "failed" || metadata.FinalURL != "http://127.0.0.1:1234/login" {
+		t.Fatalf("metadata=%+v", metadata)
+	}
+	if !containsString(metadata.Screenshots, "failure.png") || !containsString(metadata.Screenshots, "99-final.png") {
+		t.Fatalf("screenshots=%v", metadata.Screenshots)
+	}
+}
+
+func containsString(values []string, want string) bool {
+	for _, value := range values {
+		if value == want {
+			return true
+		}
+	}
+	return false
+}
+
+func TestFailedVideoSaveRetainsRawRecording(t *testing.T) {
+	dir := t.TempDir()
+	reporter := &fakeReporter{name: "TestVideoSaveFailure", failed: true}
+	s := &browserSession{t: reporter, dir: dir, started: time.Unix(1, 0).UTC(), browserVer: chromiumVersion}
+	s.screenshotOp = func(path string) error { return os.WriteFile(path, []byte("png"), 0o600) }
+	s.stopTraceOp = func(path string) error { return os.WriteFile(path, []byte("trace"), 0o600) }
+	s.closeContextOp = func() error { return nil }
+	s.saveVideoOp = func(string) error { return fmt.Errorf("injected SaveAs failure") }
+	s.finalURLOp = func() string { return "http://127.0.0.1:1234/login" }
+	if err := os.MkdirAll(filepath.Join(dir, "screenshots"), 0o700); err != nil {
+		t.Fatal(err)
+	}
+	raw := filepath.Join(dir, ".video", "raw-recording.webm")
+	if err := os.MkdirAll(filepath.Dir(raw), 0o700); err != nil {
+		t.Fatal(err)
+	}
+	if err := os.WriteFile(raw, []byte("only raw recording"), 0o600); err != nil {
+		t.Fatal(err)
+	}
+	if err := s.Finalize(); err == nil || !strings.Contains(err.Error(), "injected SaveAs failure") {
+		t.Fatalf("finalization error=%v", err)
+	}
+	if data, err := os.ReadFile(raw); err != nil || string(data) != "only raw recording" {
+		t.Fatalf("raw recording was not retained: data=%q error=%v", data, err)
+	}
+	if _, err := os.Stat(filepath.Join(dir, "video.webm")); !os.IsNotExist(err) {
+		t.Fatalf("final video should not be fabricated: %v", err)
+	}
+}
+
+func TestPartialBrowserOwnerRecordsMetadataAndCleanupError(t *testing.T) {
+	reporter := &fakeReporter{name: "TestContextConstructionFailure", failed: true}
+	root := t.TempDir()
+	s, err := newBrowserSessionOwner(reporter, root, chromiumVersion)
+	if err != nil {
+		t.Fatal(err)
+	}
+	raw := filepath.Join(s.dir, ".video", "partial.data")
+	if err := os.WriteFile(raw, []byte("partial Playwright data"), 0o600); err != nil {
+		t.Fatal(err)
+	}
+	if len(reporter.cleanups) != 1 {
+		t.Fatalf("cleanup count=%d, want 1", len(reporter.cleanups))
+	}
+	reporter.cleanups[0]()
+	if len(reporter.errors) != 1 || !strings.Contains(reporter.errors[0], "finalize browser artifacts") {
+		t.Fatalf("cleanup errors=%v", reporter.errors)
+	}
+	data, err := os.ReadFile(filepath.Join(s.dir, "session.json"))
+	if err != nil {
+		t.Fatal(err)
+	}
+	var metadata sessionMetadata
+	if err := json.Unmarshal(data, &metadata); err != nil {
+		t.Fatal(err)
+	}
+	if metadata.Outcome != "failed" {
+		t.Fatalf("metadata outcome=%q", metadata.Outcome)
+	}
+	for _, unavailable := range []string{"screenshots/99-final.png", "screenshots/failure.png", "trace.zip", "video.webm"} {
+		if _, err := os.Stat(filepath.Join(s.dir, unavailable)); !os.IsNotExist(err) {
+			t.Fatalf("unavailable artifact %s was fabricated: %v", unavailable, err)
+		}
+	}
+	if _, err := os.Stat(raw); err != nil {
+		t.Fatalf("partial raw data not retained: %v", err)
+	}
+}
+
+func TestSanitizeNameBoundsAndEmpty(t *testing.T) {
+	if sanitizeName("////") != "unnamed" {
+		t.Fatal("empty name was not replaced")
+	}
+	if got := sanitizeName(strings.Repeat("a", 200)); len(got) != 100 {
+		t.Fatalf("name length=%d", len(got))
+	}
+}
diff --git a/core/auth/ui/e2e/cache_lock_unix.go b/core/auth/ui/e2e/cache_lock_unix.go
new file mode 100644
index 0000000..16f7e89
--- /dev/null
+++ b/core/auth/ui/e2e/cache_lock_unix.go
@@ -0,0 +1,37 @@
+//go:build linux || darwin
+
+package e2e
+
+import (
+	"context"
+	"errors"
+	"os"
+	"syscall"
+	"time"
+)
+
+func acquireCacheLock(ctx context.Context, path string) (func(), error) {
+	file, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR, 0o600)
+	if err != nil {
+		return nil, err
+	}
+	for {
+		err = syscall.Flock(int(file.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)
+		if err == nil {
+			return func() {
+				_ = syscall.Flock(int(file.Fd()), syscall.LOCK_UN)
+				_ = file.Close()
+			}, nil
+		}
+		if !errors.Is(err, syscall.EWOULDBLOCK) && !errors.Is(err, syscall.EAGAIN) {
+			_ = file.Close()
+			return nil, err
+		}
+		select {
+		case <-ctx.Done():
+			_ = file.Close()
+			return nil, ctx.Err()
+		case <-time.After(25 * time.Millisecond):
+		}
+	}
+}
diff --git a/core/auth/ui/e2e/cache_lock_unsupported.go b/core/auth/ui/e2e/cache_lock_unsupported.go
new file mode 100644
index 0000000..99c4d3a
--- /dev/null
+++ b/core/auth/ui/e2e/cache_lock_unsupported.go
@@ -0,0 +1,12 @@
+//go:build !linux && !darwin
+
+package e2e
+
+import (
+	"context"
+	"fmt"
+)
+
+func acquireCacheLock(_ context.Context, _ string) (func(), error) {
+	return nil, fmt.Errorf("unsupported E2E cache-lock platform")
+}
diff --git a/core/auth/ui/e2e/config.go b/core/auth/ui/e2e/config.go
new file mode 100644
index 0000000..010b3f4
--- /dev/null
+++ b/core/auth/ui/e2e/config.go
@@ -0,0 +1,78 @@
+package e2e
+
+import (
+	"bytes"
+	"crypto/rand"
+	"encoding/hex"
+	"fmt"
+	"os"
+	"path/filepath"
+	"strings"
+	"text/template"
+)
+
+type fixtureValues struct {
+	KratosPublicURL  string
+	KratosAdminURL   string
+	KratosPublicPort int
+	KratosAdminPort  int
+	HydraPublicURL   string
+	HydraAdminURL    string
+	HydraPublicPort  int
+	HydraAdminPort   int
+	UIURL            string
+	SchemaURL        string
+	SMTPPort         int
+	CookieSecret     string
+	CipherSecret     string
+	HydraSecret      string
+}
+
+func renderFixtures(repo, configDir string, values fixtureValues) error {
+	if err := os.MkdirAll(configDir, 0o755); err != nil {
+		return err
+	}
+	schemaSource := filepath.Join(repo, "e2e", "testdata", "identity.schema.json")
+	schemaDestination := filepath.Join(configDir, "identity.schema.json")
+	data, err := os.ReadFile(schemaSource)
+	if err != nil {
+		return err
+	}
+	if err := os.WriteFile(schemaDestination, data, 0o600); err != nil {
+		return err
+	}
+	values.SchemaURL = "file://" + filepath.ToSlash(schemaDestination)
+	for _, name := range []string{"kratos.yml", "hydra.yml"} {
+		if err := renderFixture(filepath.Join(repo, "e2e", "testdata", name+".tmpl"), filepath.Join(configDir, name), values); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func renderFixture(source, destination string, values fixtureValues) error {
+	data, err := os.ReadFile(source)
+	if err != nil {
+		return err
+	}
+	tmpl, err := template.New(filepath.Base(source)).Option("missingkey=error").Parse(string(data))
+	if err != nil {
+		return err
+	}
+	var rendered bytes.Buffer
+	if err := tmpl.Execute(&rendered, values); err != nil {
+		return err
+	}
+	if strings.Contains(rendered.String(), "{{") || strings.Contains(rendered.String(), "}}") {
+		return fmt.Errorf("unresolved template marker in %s", source)
+	}
+	return os.WriteFile(destination, rendered.Bytes(), 0o600)
+}
+
+func randomSecret(bytesCount int) (string, error) {
+	b := make([]byte, bytesCount)
+	if _, err := rand.Read(b); err != nil {
+		return "", err
+	}
+	return hex.EncodeToString(b), nil
+}
diff --git a/core/auth/ui/e2e/config_test.go b/core/auth/ui/e2e/config_test.go
new file mode 100644
index 0000000..a1cf000
--- /dev/null
+++ b/core/auth/ui/e2e/config_test.go
@@ -0,0 +1,94 @@
+package e2e
+
+import (
+	"os"
+	"path/filepath"
+	"strings"
+	"testing"
+)
+
+func TestRenderFixturesContracts(t *testing.T) {
+	repo, err := repositoryDir()
+	if err != nil {
+		t.Fatal(err)
+	}
+	values := fixtureValues{
+		KratosPublicURL: "http://127.0.0.1:11001", KratosAdminURL: "http://127.0.0.1:11002",
+		KratosPublicPort: 11001, KratosAdminPort: 11002,
+		HydraPublicURL: "http://127.0.0.1:11003", HydraAdminURL: "http://127.0.0.1:11004",
+		HydraPublicPort: 11003, HydraAdminPort: 11004, UIURL: "http://127.0.0.1:11005", SMTPPort: 11007,
+		CookieSecret: strings.Repeat("a", 32), CipherSecret: strings.Repeat("b", 32), HydraSecret: strings.Repeat("c", 64),
+	}
+	first, second := t.TempDir(), t.TempDir()
+	if err := renderFixtures(repo, first, values); err != nil {
+		t.Fatal(err)
+	}
+	if err := renderFixtures(repo, second, values); err != nil {
+		t.Fatal(err)
+	}
+	for _, name := range []string{"kratos.yml", "hydra.yml", "identity.schema.json"} {
+		a, err := os.ReadFile(filepath.Join(first, name))
+		if err != nil {
+			t.Fatal(err)
+		}
+		b, err := os.ReadFile(filepath.Join(second, name))
+		if err != nil {
+			t.Fatal(err)
+		}
+		normalizedA := strings.ReplaceAll(string(a), filepath.ToSlash(first), "<CONFIG>")
+		normalizedB := strings.ReplaceAll(string(b), filepath.ToSlash(second), "<CONFIG>")
+		if normalizedA != normalizedB {
+			t.Errorf("%s rendering is not deterministic", name)
+		}
+		if strings.Contains(string(a), "{{") || strings.Contains(string(a), "}}") {
+			t.Errorf("%s has unresolved placeholder", name)
+		}
+	}
+	kratos, _ := os.ReadFile(filepath.Join(first, "kratos.yml"))
+	for _, required := range []string{"dsn: memory", "default_schema_id: user", "id: user", "password:\n      enabled: true", "hook: session", "leak_sensitive_values: false", "smtp://e2e:e2e@127.0.0.1:11007", "http://127.0.0.1:11005/login", "file://"} {
+		if !strings.Contains(string(kratos), required) {
+			t.Errorf("kratos config missing %q", required)
+		}
+	}
+	if strings.Count(string(kratos), "host: 127.0.0.1") != 2 {
+		t.Errorf("Kratos listeners are not both loopback-bound: %s", kratos)
+	}
+	hydra, _ := os.ReadFile(filepath.Join(first, "hydra.yml"))
+	for _, required := range []string{"dsn: memory", "port: 11003", "port: 11004", "issuer: http://127.0.0.1:11003/", "login: http://127.0.0.1:11005/login", "consent: http://127.0.0.1:11005/consent", "leak_sensitive_values: false"} {
+		if !strings.Contains(string(hydra), required) {
+			t.Errorf("hydra config missing %q", required)
+		}
+	}
+	if strings.Count(string(hydra), "host: 127.0.0.1") != 2 {
+		t.Errorf("Hydra listeners are not both loopback-bound: %s", hydra)
+	}
+	schema, _ := os.ReadFile(filepath.Join(first, "identity.schema.json"))
+	for _, required := range []string{
+		`"$id": "https://schemas.ory.sh/presets/kratos/quickstart/email-password/identity.schema.json"`,
+		`"title": "User"`,
+		`"username"`,
+		`"format": "username"`,
+		`"title": "Username"`,
+		`"minLength": 3`,
+		`"password"`,
+		`"identifier": true`,
+		`"additionalProperties": false`,
+	} {
+		if !strings.Contains(string(schema), required) {
+			t.Errorf("schema missing production contract %q", required)
+		}
+	}
+	if strings.Contains(string(schema), `"required"`) {
+		t.Error("schema unexpectedly diverges from production with required traits")
+	}
+}
+
+func TestRenderFixtureRejectsMissingValue(t *testing.T) {
+	source := filepath.Join(t.TempDir(), "fixture.tmpl")
+	if err := os.WriteFile(source, []byte("{{.DoesNotExist}}"), 0o600); err != nil {
+		t.Fatal(err)
+	}
+	if err := renderFixture(source, filepath.Join(t.TempDir(), "out"), fixtureValues{}); err == nil {
+		t.Fatal("expected invalid template error")
+	}
+}
diff --git a/core/auth/ui/e2e/doc.go b/core/auth/ui/e2e/doc.go
new file mode 100644
index 0000000..66136f3
--- /dev/null
+++ b/core/auth/ui/e2e/doc.go
@@ -0,0 +1,4 @@
+// Package e2e provides the native Ory and Playwright end-to-end test harness.
+// Full-stack tests are opt-in through the e2e build tag; untagged tests are pure
+// unit tests and never download or start Ory or Playwright.
+package e2e
diff --git a/core/auth/ui/e2e/hydra_test.go b/core/auth/ui/e2e/hydra_test.go
new file mode 100644
index 0000000..84e4e38
--- /dev/null
+++ b/core/auth/ui/e2e/hydra_test.go
@@ -0,0 +1,309 @@
+//go:build e2e
+
+package e2e
+
+import (
+	"context"
+	"encoding/json"
+	"net/http"
+	"net/url"
+	"path/filepath"
+	"strings"
+	"testing"
+	"time"
+)
+
+type workflowStep struct {
+	origin string
+	path   string
+}
+
+func TestHydraAuthorizationCode(t *testing.T) {
+	session, callbacks := newHydraTestSession(t)
+	client := newDirectAPIClient(testStack.KratosURL, testStack.KratosAdmin)
+	defer client.close()
+	username, password := uniqueKratosCredentials(t)
+
+	status, body := postIdentityJSON(t, client, username, password)
+	if status != http.StatusOK {
+		t.Fatalf("create unique OAuth user returned status %d: %s", status, sanitizedResponseDiagnostic(body))
+	}
+	var identity identityAPIResponse
+	if err := json.Unmarshal(body, &identity); err != nil || identity.ID == "" {
+		t.Fatal("create unique OAuth user did not return a non-empty identity id")
+	}
+
+	clientToken, err := randomSecret(12)
+	if err != nil {
+		t.Fatal("generate unique OAuth client id")
+	}
+	clientSecret, err := randomSecret(24)
+	if err != nil {
+		t.Fatal("generate unique OAuth client secret")
+	}
+	clientID := "e2e-client-" + clientToken
+	requestedClient := hydraOAuthClient{
+		ClientID:                clientID,
+		ClientSecret:            clientSecret,
+		RedirectURIs:            []string{callbacks.URI()},
+		GrantTypes:              []string{"authorization_code"},
+		ResponseTypes:           []string{"code"},
+		Scope:                   "openid",
+		TokenEndpointAuthMethod: "client_secret_basic",
+	}
+	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+	created, err := client.createHydraOAuthClient(ctx, testStack.HydraAdmin, requestedClient)
+	cancel()
+	if err != nil {
+		t.Fatal(err)
+	}
+	if created.ClientID != clientID {
+		t.Fatal("Hydra Admin did not create the unique confidential client")
+	}
+
+	state := uniqueOAuthValue(t, "state")
+	nonce := uniqueOAuthValue(t, "nonce")
+	firstAttempt, err := callbacks.Begin()
+	if err != nil {
+		t.Fatal(err)
+	}
+	if _, err := session.Page.Goto(hydraAuthorizationURL(testStack.HydraURL, clientID, callbacks.URI(), state, nonce)); err != nil {
+		t.Fatal("navigate to bounded Hydra authorization request")
+	}
+	checkpoint(t, session, "authorization-start")
+	assertKratosForm(t, session.Page, "/login")
+	checkpoint(t, session, "authorization-login-form")
+	fillCredentials(t, session.Page, username, password)
+	clickButton(t, session.Page, "login")
+	checkpoint(t, session, "post-login-automatic-consent")
+
+	firstCallback, err := firstAttempt.Wait(context.Background())
+	if err != nil {
+		t.Fatal(err)
+	}
+	firstCode, err := validateOAuthCallback(firstCallback, state)
+	if err != nil {
+		t.Fatal(err)
+	}
+	assertCallbackPage(t, session, callbacks)
+	checkpoint(t, session, "callback-completion")
+	if err := firstAttempt.Finish(context.Background()); err != nil {
+		t.Fatal(err)
+	}
+
+	firstSequenceEnd := len(session.RequestMetadata())
+	assertHydraLoggedOutSequence(t, session.RequestMetadata()[:firstSequenceEnd], callbacks.Origin())
+	firstTokens := exchangeAndValidateHydraCode(t, client, clientID, clientSecret, callbacks.URI(), firstCode, username, nonce)
+	if firstTokens.AccessToken == "" || firstTokens.IDToken == "" {
+		t.Fatal("Hydra token response did not contain non-empty access and ID tokens")
+	}
+
+	status, _, replayError, err := client.exchangeHydraAuthorizationCode(context.Background(), testStack.HydraURL, clientID, clientSecret, callbacks.URI(), firstCode)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if status != http.StatusBadRequest || replayError.Error != "invalid_grant" {
+		t.Fatalf("authorization-code replay returned status %d without invalid_grant", status)
+	}
+
+	secondState := uniqueOAuthValue(t, "state")
+	secondNonce := uniqueOAuthValue(t, "nonce")
+	secondAttempt, err := callbacks.Begin()
+	if err != nil {
+		t.Fatal(err)
+	}
+	beforeSecond := len(session.RequestMetadata())
+	if _, err := session.Page.Goto(hydraAuthorizationURL(testStack.HydraURL, clientID, callbacks.URI(), secondState, secondNonce)); err != nil {
+		t.Fatal("navigate to second bounded Hydra authorization request")
+	}
+	secondCallback, err := secondAttempt.Wait(context.Background())
+	if err != nil {
+		t.Fatal(err)
+	}
+	secondCode, err := validateOAuthCallback(secondCallback, secondState)
+	if err != nil {
+		t.Fatal(err)
+	}
+	assertCallbackPage(t, session, callbacks)
+	if count, err := session.Page.Locator(`input[name="password"]`).Count(); err != nil || count != 0 {
+		t.Fatalf("second authorization rendered another password form: count=%d", count)
+	}
+	checkpoint(t, session, "second-authenticated-callback")
+	if err := secondAttempt.Finish(context.Background()); err != nil {
+		t.Fatal(err)
+	}
+	assertSecondAuthorizationUsesExistingSession(t, session.RequestMetadata()[beforeSecond:])
+	_ = exchangeAndValidateHydraCode(t, client, clientID, clientSecret, callbacks.URI(), secondCode, username, secondNonce)
+}
+
+func newHydraTestSession(t *testing.T) (*browserSession, *callbackCapture) {
+	t.Helper()
+	callbacks, err := startCallbackCapture()
+	if err != nil {
+		t.Fatal(err)
+	}
+	transferred := false
+	defer func() {
+		if !transferred {
+			if err := callbacks.Close(); err != nil {
+				t.Errorf("close callback listener after browser setup failure: %v", err)
+			}
+		}
+	}()
+	dir := filepath.Join(testStack.ArtifactDir, sanitizeName(t.Name()))
+	failedBeforeFinalize := false
+	t.Cleanup(func() { assertArtifactSet(t, dir, failedBeforeFinalize) })
+	session, err := newBrowserSession(t, testBrowser.Browser, testStack.ArtifactDir, []string{testStack.UIURL, testStack.KratosURL, testStack.HydraURL, callbacks.Origin()})
+	if err != nil {
+		t.Fatal(err)
+	}
+	t.Cleanup(func() { failedBeforeFinalize = t.Failed() })
+	t.Cleanup(func() { assertHydraBrowserOrigins(t, session, callbacks.Origin()) })
+	// Registered last so callback shutdown runs first. A shutdown failure marks
+	// the test failed before failure.png, failed session metadata, and artifact
+	// validation are finalized by the earlier LIFO cleanups.
+	t.Cleanup(func() {
+		if err := callbacks.Close(); err != nil {
+			t.Errorf("close callback listener: %v", err)
+		}
+	})
+	transferred = true
+	return session, callbacks
+}
+
+func uniqueOAuthValue(t *testing.T, prefix string) string {
+	t.Helper()
+	value, err := randomSecret(16)
+	if err != nil {
+		t.Fatalf("generate unique OAuth %s", prefix)
+	}
+	return prefix + "-" + value
+}
+
+func hydraAuthorizationURL(hydraPublic, clientID, redirectURI, state, nonce string) string {
+	values := url.Values{
+		"client_id":     {clientID},
+		"redirect_uri":  {redirectURI},
+		"response_type": {"code"},
+		"scope":         {"openid"},
+		"state":         {state},
+		"nonce":         {nonce},
+	}
+	return strings.TrimRight(hydraPublic, "/") + "/oauth2/auth?" + values.Encode()
+}
+
+func assertCallbackPage(t *testing.T, session *browserSession, callbacks *callbackCapture) {
+	t.Helper()
+	current, err := url.Parse(session.Page.URL())
+	if err != nil || current.Scheme+"://"+current.Host != callbacks.Origin() || current.Path != "/callback" {
+		t.Fatal("authorization did not finish at the owned loopback callback")
+	}
+	body, err := session.Page.Locator("body").InnerText()
+	if err != nil || !strings.Contains(body, "Authorization callback received.") {
+		t.Fatal("owned loopback callback completion was not visible")
+	}
+}
+
+func exchangeAndValidateHydraCode(t *testing.T, client *directAPIClient, clientID, clientSecret, redirectURI, code, username, nonce string) hydraTokenResponse {
+	t.Helper()
+	status, tokens, oauthErr, err := client.exchangeHydraAuthorizationCode(context.Background(), testStack.HydraURL, clientID, clientSecret, redirectURI, code)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if status != http.StatusOK || oauthErr.Error != "" {
+		t.Fatalf("Hydra authorization-code exchange returned status %d", status)
+	}
+	if !strings.EqualFold(tokens.TokenType, "bearer") || tokens.AccessToken == "" || tokens.IDToken == "" {
+		t.Fatal("Hydra token response omitted the bearer token type, access token, or ID token")
+	}
+	claims, err := decodeJWTPayloadUnverified(tokens.IDToken)
+	if err != nil {
+		t.Fatal(err)
+	}
+	expected := map[string]string{
+		"sub": username, "username": username, "email": username + "@example.test",
+		"iss": testStack.HydraURL + "/", "nonce": nonce,
+	}
+	for name, want := range expected {
+		if got, ok := jwtStringClaim(claims, name); !ok || got != want {
+			t.Fatalf("ID-token payload claim %s did not match", name)
+		}
+	}
+	if !jwtAudienceContains(claims, clientID) {
+		t.Fatal("ID-token payload audience did not include the generated client id")
+	}
+	return tokens
+}
+
+func assertHydraLoggedOutSequence(t *testing.T, metadata []requestMetadata, callbackOrigin string) {
+	t.Helper()
+	expected := []workflowStep{
+		{testStack.HydraURL, "/oauth2/auth"},
+		{testStack.UIURL, "/login"},
+		{testStack.KratosURL, "/self-service/login/browser"},
+		{testStack.UIURL, "/login"},
+		{testStack.HydraURL, "/oauth2/auth"},
+		{testStack.UIURL, "/consent"},
+		{testStack.HydraURL, "/oauth2/auth"},
+		{callbackOrigin, "/callback"},
+	}
+	index := 0
+	for _, request := range metadata {
+		if request.Status < http.StatusOK || request.Status >= http.StatusBadRequest || index == len(expected) {
+			continue
+		}
+		if request.Origin == expected[index].origin && request.Path == expected[index].path {
+			index++
+		}
+	}
+	if index != len(expected) {
+		t.Fatalf("sanitized Hydra workflow sequence stopped before required step %d of %d", index+1, len(expected))
+	}
+}
+
+func assertSecondAuthorizationUsesExistingSession(t *testing.T, metadata []requestMetadata) {
+	t.Helper()
+	observedUILoginGET := false
+	for _, request := range metadata {
+		if request.Status < http.StatusOK || request.Status >= http.StatusBadRequest {
+			continue
+		}
+		if request.Method == http.MethodGet && request.Origin == testStack.UIURL && request.Path == "/login" {
+			observedUILoginGET = true
+		}
+		if request.Origin == testStack.KratosURL && request.Path == "/self-service/login/browser" {
+			t.Fatal("second authorization initiated another Kratos browser login flow")
+		}
+		if request.Method == http.MethodPost && request.Origin == testStack.UIURL && request.Path == "/login" {
+			t.Fatal("second authorization submitted another login form")
+		}
+	}
+	if !observedUILoginGET {
+		t.Fatal("second authorization did not exercise auth-ui's existing-session GET /login branch")
+	}
+}
+
+func assertHydraBrowserOrigins(t *testing.T, session *browserSession, callbackOrigin string) {
+	t.Helper()
+	expected := map[string]bool{testStack.UIURL: false, testStack.KratosURL: false, testStack.HydraURL: false, callbackOrigin: false}
+	for _, request := range session.RequestMetadata() {
+		if request.Status < http.StatusOK || request.Status >= http.StatusBadRequest {
+			continue
+		}
+		if _, ok := expected[request.Origin]; !ok {
+			t.Errorf("browser received a successful response from unexpected origin %s%s", request.Origin, request.Path)
+			continue
+		}
+		expected[request.Origin] = true
+	}
+	for origin, observed := range expected {
+		if !observed {
+			t.Errorf("browser did not receive an expected successful OAuth workflow response from %s", origin)
+		}
+	}
+	for _, request := range session.BlockedRequests() {
+		if !isExpectedBlockedBrowserRequest(request) {
+			t.Errorf("browser blocked an unexpected query-free target %s", request)
+		}
+	}
+}
diff --git a/core/auth/ui/e2e/kratos_test.go b/core/auth/ui/e2e/kratos_test.go
new file mode 100644
index 0000000..d909b1d
--- /dev/null
+++ b/core/auth/ui/e2e/kratos_test.go
@@ -0,0 +1,339 @@
+//go:build e2e
+
+package e2e
+
+import (
+	"context"
+	"fmt"
+	"net/http"
+	"net/url"
+	"path/filepath"
+	"strings"
+	"testing"
+	"time"
+
+	playwright "github.com/mxschmitt/playwright-go"
+)
+
+func TestKratosUnauthenticatedLanding(t *testing.T) {
+	session := newKratosTestSession(t)
+	client := newDirectAPIClient(testStack.KratosURL, testStack.KratosAdmin)
+	defer client.close()
+
+	if _, err := session.Page.Goto(testStack.UIURL + "/"); err != nil {
+		t.Fatal(err)
+	}
+	assertKratosForm(t, session.Page, "/login")
+	checkpoint(t, session, "unauthenticated-login-form")
+	assertNoAcceptedKratosSession(t, client, session)
+}
+
+func TestKratosRegistrationAndWhoAmI(t *testing.T) {
+	session := newKratosTestSession(t)
+	client := newDirectAPIClient(testStack.KratosURL, testStack.KratosAdmin)
+	defer client.close()
+	username, password := uniqueKratosCredentials(t)
+
+	registerThroughBrowser(t, session, username, password, "registration")
+	whoami := assertAcceptedKratosSession(t, client, session)
+	if whoami.Identity.Traits.Username != username || whoami.Identity.ID == "" {
+		t.Fatal("Kratos whoami did not return the registered identity ID and username")
+	}
+}
+
+func TestKratosDuplicateRegistration(t *testing.T) {
+	session := newKratosTestSession(t)
+	client := newDirectAPIClient(testStack.KratosURL, testStack.KratosAdmin)
+	defer client.close()
+	username, password := uniqueKratosCredentials(t)
+
+	registerThroughBrowser(t, session, username, password, "initial-registration")
+	first := assertAcceptedKratosSession(t, client, session)
+	if err := session.Context.ClearCookies(); err != nil {
+		t.Fatal(err)
+	}
+	assertNoAcceptedKratosSession(t, client, session)
+
+	openKratosForm(t, session.Page, testStack.UIURL+"/register", "/register")
+	checkpoint(t, session, "duplicate-registration-form")
+	fillCredentials(t, session.Page, username, password)
+	clickButton(t, session.Page, "Create Account")
+	assertKratosForm(t, session.Page, "/login")
+	checkpoint(t, session, "duplicate-registration-return-login")
+	assertNoAcceptedKratosSession(t, client, session)
+
+	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+	defer cancel()
+	identities, err := client.kratosIdentitiesByUsername(ctx, username)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(identities) != 1 || identities[0].ID != first.Identity.ID {
+		t.Fatalf("duplicate registration identity count=%d, want exactly one unchanged identity", len(identities))
+	}
+}
+
+func TestKratosLogoutInvalidatesSession(t *testing.T) {
+	session := newKratosTestSession(t)
+	client := newDirectAPIClient(testStack.KratosURL, testStack.KratosAdmin)
+	defer client.close()
+	username, password := uniqueKratosCredentials(t)
+
+	registerThroughBrowser(t, session, username, password, "registration-before-logout")
+	acceptedCookies := browserKratosCookies(t, session)
+	if _, accepted, err := client.kratosWhoAmI(context.Background(), acceptedCookies); err != nil || !accepted {
+		t.Fatalf("registered Kratos session was not accepted before logout: accepted=%v err=%v", accepted, err)
+	}
+	clickLink(t, session.Page, "logout")
+	assertKratosForm(t, session.Page, "/login")
+	checkpoint(t, session, "logout-return-login")
+
+	if _, accepted, err := client.kratosWhoAmI(context.Background(), acceptedCookies); err != nil {
+		t.Fatal(err)
+	} else if accepted {
+		t.Fatal("Kratos continued accepting the logged-out session")
+	}
+	assertNoAcceptedKratosSession(t, client, session)
+}
+
+func TestKratosValidLaterLogin(t *testing.T) {
+	session := newKratosTestSession(t)
+	client := newDirectAPIClient(testStack.KratosURL, testStack.KratosAdmin)
+	defer client.close()
+	username, password := uniqueKratosCredentials(t)
+
+	registerThroughBrowser(t, session, username, password, "registration-before-login")
+	registered := assertAcceptedKratosSession(t, client, session)
+	clickLink(t, session.Page, "logout")
+	assertKratosForm(t, session.Page, "/login")
+	checkpoint(t, session, "later-login-form")
+	fillCredentials(t, session.Page, username, password)
+	clickButton(t, session.Page, "login")
+	assertGreeting(t, session.Page, username)
+	checkpoint(t, session, "later-login-greeting")
+	loggedIn := assertAcceptedKratosSession(t, client, session)
+	if loggedIn.Identity.ID != registered.Identity.ID || loggedIn.Identity.Traits.Username != username {
+		t.Fatal("later login did not restore the original Kratos identity")
+	}
+}
+
+func TestKratosWrongPasswordRejected(t *testing.T) {
+	session := newKratosTestSession(t)
+	client := newDirectAPIClient(testStack.KratosURL, testStack.KratosAdmin)
+	defer client.close()
+	username, password := uniqueKratosCredentials(t)
+	_, wrongPassword := uniqueKratosCredentials(t)
+
+	registerThroughBrowser(t, session, username, password, "registration-before-wrong-password")
+	clickLink(t, session.Page, "logout")
+	assertKratosForm(t, session.Page, "/login")
+	checkpoint(t, session, "wrong-password-login-form")
+	fillCredentials(t, session.Page, username, wrongPassword)
+	clickButton(t, session.Page, "login")
+	assertKratosForm(t, session.Page, "/login")
+	checkpoint(t, session, "wrong-password-return-login")
+	assertNoAcceptedKratosSession(t, client, session)
+}
+
+func TestKratosUnknownUsernameRejected(t *testing.T) {
+	session := newKratosTestSession(t)
+	client := newDirectAPIClient(testStack.KratosURL, testStack.KratosAdmin)
+	defer client.close()
+	username, password := uniqueKratosCredentials(t)
+
+	openKratosForm(t, session.Page, testStack.UIURL+"/login", "/login")
+	checkpoint(t, session, "unknown-username-login-form")
+	fillCredentials(t, session.Page, username, password)
+	clickButton(t, session.Page, "login")
+	assertKratosForm(t, session.Page, "/login")
+	checkpoint(t, session, "unknown-username-return-login")
+	assertNoAcceptedKratosSession(t, client, session)
+
+	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+	defer cancel()
+	identities, err := client.kratosIdentitiesByUsername(ctx, username)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(identities) != 0 {
+		t.Fatalf("unknown-username login unexpectedly matched %d identities", len(identities))
+	}
+}
+
+func newKratosTestSession(t *testing.T) *browserSession {
+	t.Helper()
+	dir := filepath.Join(testStack.ArtifactDir, sanitizeName(t.Name()))
+	failedBeforeFinalize := false
+	t.Cleanup(func() { assertArtifactSet(t, dir, failedBeforeFinalize) })
+	session, err := newBrowserSession(t, testBrowser.Browser, testStack.ArtifactDir, []string{testStack.UIURL, testStack.KratosURL})
+	if err != nil {
+		t.Fatal(err)
+	}
+	t.Cleanup(func() { failedBeforeFinalize = t.Failed() })
+	t.Cleanup(func() { assertKratosBrowserOrigins(t, session) })
+	return session
+}
+
+func uniqueKratosCredentials(t *testing.T) (string, string) {
+	t.Helper()
+	usernameToken, err := randomSecret(10)
+	if err != nil {
+		t.Fatal("generate unique test-local username")
+	}
+	passwordToken, err := randomSecret(14)
+	if err != nil {
+		t.Fatal("generate unique test-local password")
+	}
+	return "e2e-" + usernameToken, "Correct-Horse-" + passwordToken + "-9!"
+}
+
+func registerThroughBrowser(t *testing.T, session *browserSession, username, password, checkpointPrefix string) {
+	t.Helper()
+	openKratosForm(t, session.Page, testStack.UIURL+"/register", "/register")
+	checkpoint(t, session, checkpointPrefix+"-form")
+	fillCredentials(t, session.Page, username, password)
+	clickButton(t, session.Page, "Create Account")
+	assertGreeting(t, session.Page, username)
+	checkpoint(t, session, checkpointPrefix+"-greeting")
+}
+
+func openKratosForm(t *testing.T, page playwright.Page, address, route string) {
+	t.Helper()
+	if _, err := page.Goto(address); err != nil {
+		t.Fatal(err)
+	}
+	assertKratosForm(t, page, route)
+}
+
+func assertKratosForm(t *testing.T, page playwright.Page, route string) {
+	t.Helper()
+	u, err := url.Parse(page.URL())
+	if err != nil || u.Scheme+"://"+u.Host != testStack.UIURL || u.Path != route || u.Query().Get("flow") == "" {
+		t.Fatalf("expected rendered %s flow at the UI origin", route)
+	}
+	for _, selector := range []string{`input[name="username"]`, `input[name="password"]`} {
+		if err := page.Locator(selector).WaitFor(playwright.LocatorWaitForOptions{State: playwright.WaitForSelectorStateVisible, Timeout: playwright.Float(10_000)}); err != nil {
+			t.Fatalf("required credential field %s did not become visible: %v", selector, err)
+		}
+	}
+	csrf := page.Locator(`input[name="csrf_token"]`)
+	if err := csrf.WaitFor(playwright.LocatorWaitForOptions{State: playwright.WaitForSelectorStateAttached, Timeout: playwright.Float(10_000)}); err != nil {
+		t.Fatalf("rendered flow CSRF field was not attached: %v", err)
+	}
+	count, err := csrf.Count()
+	if err != nil || count != 1 {
+		t.Fatalf("rendered flow does not contain exactly one CSRF field: count=%d err=%v", count, err)
+	}
+}
+
+func fillCredentials(t *testing.T, page playwright.Page, username, password string) {
+	t.Helper()
+	if err := page.Locator(`input[name="username"]`).Fill(username); err != nil {
+		t.Fatal("fill username field")
+	}
+	if err := page.Locator(`input[name="password"]`).Fill(password); err != nil {
+		t.Fatal("fill password field")
+	}
+}
+
+func clickButton(t *testing.T, page playwright.Page, name string) {
+	t.Helper()
+	if err := page.GetByRole("button", playwright.PageGetByRoleOptions{Name: name, Exact: playwright.Bool(true)}).Click(); err != nil {
+		t.Fatalf("click %s button: %v", name, err)
+	}
+}
+
+func clickLink(t *testing.T, page playwright.Page, name string) {
+	t.Helper()
+	if err := page.GetByText(name, playwright.PageGetByTextOptions{Exact: playwright.Bool(true)}).Click(); err != nil {
+		t.Fatalf("click %s link: %v", name, err)
+	}
+}
+
+func assertGreeting(t *testing.T, page playwright.Page, username string) {
+	t.Helper()
+	u, err := url.Parse(page.URL())
+	if err != nil || u.Scheme+"://"+u.Host != testStack.UIURL || u.Path != "/" {
+		t.Fatal("successful authentication did not return to the UI landing route")
+	}
+	body, err := page.Locator("body").InnerText()
+	if err != nil || !strings.Contains(body, fmt.Sprintf("Hello %s!", username)) {
+		t.Fatalf("authenticated greeting is not visible: %v", err)
+	}
+}
+
+func checkpoint(t *testing.T, session *browserSession, name string) {
+	t.Helper()
+	if err := session.Checkpoint(name); err != nil {
+		t.Fatalf("capture checkpoint %s: %v", name, err)
+	}
+}
+
+func browserKratosCookies(t *testing.T, session *browserSession) []*http.Cookie {
+	t.Helper()
+	cookies, err := session.Context.Cookies(testStack.KratosURL)
+	if err != nil {
+		t.Fatal("export browser cookies for bounded Kratos assertion")
+	}
+	result := make([]*http.Cookie, 0, len(cookies))
+	for _, cookie := range cookies {
+		result = append(result, &http.Cookie{Name: cookie.Name, Value: cookie.Value, Path: cookie.Path, Domain: cookie.Domain, Secure: cookie.Secure, HttpOnly: cookie.HttpOnly})
+	}
+	return result
+}
+
+func assertAcceptedKratosSession(t *testing.T, client *directAPIClient, browser *browserSession) kratosSession {
+	t.Helper()
+	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+	defer cancel()
+	session, accepted, err := client.kratosWhoAmI(ctx, browserKratosCookies(t, browser))
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !accepted {
+		t.Fatal("browser cookies were not accepted as an active Kratos session")
+	}
+	return session
+}
+
+func assertNoAcceptedKratosSession(t *testing.T, client *directAPIClient, browser *browserSession) {
+	t.Helper()
+	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+	defer cancel()
+	_, accepted, err := client.kratosWhoAmI(ctx, browserKratosCookies(t, browser))
+	if err != nil {
+		t.Fatal(err)
+	}
+	if accepted {
+		t.Fatal("browser received cookies accepted as an active Kratos session")
+	}
+}
+
+func assertKratosBrowserOrigins(t *testing.T, session *browserSession) {
+	t.Helper()
+	expected := map[string]bool{testStack.UIURL: false, testStack.KratosURL: false}
+	for _, request := range session.RequestMetadata() {
+		if request.Status < http.StatusOK || request.Status >= http.StatusBadRequest {
+			continue
+		}
+		if _, ok := expected[request.Origin]; !ok {
+			t.Errorf("browser received a successful response from unexpected origin %s%s", request.Origin, request.Path)
+			continue
+		}
+		expected[request.Origin] = true
+	}
+	for origin, observed := range expected {
+		if !observed {
+			t.Errorf("browser did not receive an expected successful workflow response from %s", origin)
+		}
+	}
+	blocked := session.BlockedRequests()
+	if len(blocked) == 0 {
+		t.Error("browser did not block the expected external CDN font request")
+	}
+	for _, request := range blocked {
+		if !isExpectedBlockedBrowserRequest(request) {
+			t.Errorf("browser blocked an unexpected query-free target %s", request)
+		}
+	}
+}
diff --git a/core/auth/ui/e2e/oauth_helpers.go b/core/auth/ui/e2e/oauth_helpers.go
new file mode 100644
index 0000000..d7efa73
--- /dev/null
+++ b/core/auth/ui/e2e/oauth_helpers.go
@@ -0,0 +1,347 @@
+package e2e
+
+import (
+	"context"
+	"encoding/base64"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"io"
+	"net"
+	"net/http"
+	"net/url"
+	"regexp"
+	"strings"
+	"sync"
+	"time"
+)
+
+const (
+	callbackWaitTimeout  = 10 * time.Second
+	callbackCloseTimeout = 2 * time.Second
+	maxJWTPayload        = 32 << 10
+)
+
+type hydraOAuthClient struct {
+	ClientID                string   `json:"client_id"`
+	ClientSecret            string   `json:"client_secret"`
+	RedirectURIs            []string `json:"redirect_uris"`
+	GrantTypes              []string `json:"grant_types"`
+	ResponseTypes           []string `json:"response_types"`
+	Scope                   string   `json:"scope"`
+	TokenEndpointAuthMethod string   `json:"token_endpoint_auth_method"`
+}
+
+type hydraTokenResponse struct {
+	AccessToken string `json:"access_token"`
+	IDToken     string `json:"id_token"`
+	TokenType   string `json:"token_type"`
+}
+
+type oauthTokenError struct {
+	Error string `json:"error"`
+}
+
+func (c *directAPIClient) createHydraOAuthClient(ctx context.Context, hydraAdmin string, requested hydraOAuthClient) (hydraOAuthClient, error) {
+	var created hydraOAuthClient
+	body, err := json.Marshal(requested)
+	if err != nil {
+		return created, fmt.Errorf("encode Hydra OAuth client request")
+	}
+	status, response, err := c.postJSON(ctx, strings.TrimRight(hydraAdmin, "/")+"/admin/clients", body)
+	if err != nil {
+		return created, err
+	}
+	if status != http.StatusCreated {
+		return created, unexpectedDirectAPIStatus(http.MethodPost, "/admin/clients", status, response)
+	}
+	if err := json.Unmarshal(response, &created); err != nil {
+		return created, fmt.Errorf("decode Hydra OAuth client response: invalid JSON")
+	}
+	if created.ClientID == "" || created.ClientID != requested.ClientID {
+		return created, fmt.Errorf("Hydra OAuth client response did not contain the requested client id")
+	}
+	return created, nil
+}
+
+func (c *directAPIClient) exchangeHydraAuthorizationCode(ctx context.Context, hydraPublic, clientID, clientSecret, redirectURI, code string) (int, hydraTokenResponse, oauthTokenError, error) {
+	var tokens hydraTokenResponse
+	var oauthErr oauthTokenError
+	ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
+	defer cancel()
+	form := url.Values{
+		"grant_type":   {"authorization_code"},
+		"code":         {code},
+		"redirect_uri": {redirectURI},
+	}
+	req, err := http.NewRequestWithContext(ctx, http.MethodPost, strings.TrimRight(hydraPublic, "/")+"/oauth2/token", strings.NewReader(form.Encode()))
+	if err != nil {
+		return 0, tokens, oauthErr, fmt.Errorf("construct bounded Hydra token request")
+	}
+	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+	req.SetBasicAuth(clientID, clientSecret)
+	status, body, err := c.do(ctx, req)
+	if err != nil {
+		return 0, tokens, oauthErr, err
+	}
+	if status == http.StatusOK {
+		if err := json.Unmarshal(body, &tokens); err != nil {
+			return status, tokens, oauthErr, fmt.Errorf("decode Hydra token response: invalid JSON")
+		}
+		return status, tokens, oauthErr, nil
+	}
+	if err := json.Unmarshal(body, &oauthErr); err != nil {
+		return status, tokens, oauthErr, unexpectedDirectAPIStatus(http.MethodPost, "/oauth2/token", status, body)
+	}
+	oauthErr.Error = sanitizedOAuthErrorCode(oauthErr.Error)
+	return status, tokens, oauthErr, nil
+}
+
+var oauthErrorCode = regexp.MustCompile(`^[A-Za-z_]{1,64}$`)
+
+func sanitizedOAuthErrorCode(value string) string {
+	if oauthErrorCode.MatchString(value) {
+		return value
+	}
+	return "invalid_response"
+}
+
+// decodeJWTPayloadUnverified decodes only the middle base64url segment of a JWT.
+// It deliberately performs no signature, algorithm, issuer, or key validation.
+func decodeJWTPayloadUnverified(token string) (map[string]any, error) {
+	parts := strings.Split(token, ".")
+	if len(parts) != 3 || parts[1] == "" {
+		return nil, fmt.Errorf("decode JWT payload: expected three compact segments")
+	}
+	if len(parts[1]) > base64.RawURLEncoding.EncodedLen(maxJWTPayload) {
+		return nil, fmt.Errorf("decode JWT payload: payload exceeds %d bytes", maxJWTPayload)
+	}
+	payload, err := base64.RawURLEncoding.DecodeString(parts[1])
+	if err != nil {
+		return nil, fmt.Errorf("decode JWT payload: invalid base64url")
+	}
+	if len(payload) > maxJWTPayload {
+		return nil, fmt.Errorf("decode JWT payload: payload exceeds %d bytes", maxJWTPayload)
+	}
+	var claims map[string]any
+	if err := json.Unmarshal(payload, &claims); err != nil || claims == nil {
+		return nil, fmt.Errorf("decode JWT payload: invalid JSON object")
+	}
+	return claims, nil
+}
+
+func jwtStringClaim(claims map[string]any, name string) (string, bool) {
+	value, ok := claims[name].(string)
+	return value, ok && value != ""
+}
+
+func jwtAudienceContains(claims map[string]any, expected string) bool {
+	switch audience := claims["aud"].(type) {
+	case string:
+		return audience == expected
+	case []any:
+		for _, value := range audience {
+			if text, ok := value.(string); ok && text == expected {
+				return true
+			}
+		}
+	}
+	return false
+}
+
+type oauthCallback struct {
+	Code  []string
+	State []string
+	Error []string
+}
+
+type callbackAttempt struct {
+	capture *callbackCapture
+	result  chan oauthCallback
+	count   int
+	done    bool
+}
+
+type callbackCapture struct {
+	listener     net.Listener
+	server       *http.Server
+	serveDone    chan error
+	closing      chan struct{}
+	closeTimeout time.Duration
+	closeOnce    sync.Once
+	closeErr     error
+	mu           sync.Mutex
+	active       *callbackAttempt
+	closed       bool
+}
+
+func startCallbackCapture() (*callbackCapture, error) {
+	listener, err := net.Listen("tcp", "127.0.0.1:0")
+	if err != nil {
+		return nil, fmt.Errorf("bind OAuth callback listener: %w", err)
+	}
+	capture := &callbackCapture{
+		listener:     listener,
+		serveDone:    make(chan error, 1),
+		closing:      make(chan struct{}),
+		closeTimeout: callbackCloseTimeout,
+	}
+	mux := http.NewServeMux()
+	mux.HandleFunc("/callback", capture.handle)
+	capture.server = &http.Server{
+		Handler:           mux,
+		ReadHeaderTimeout: 2 * time.Second,
+		ReadTimeout:       5 * time.Second,
+		WriteTimeout:      5 * time.Second,
+		IdleTimeout:       5 * time.Second,
+	}
+	go func() { capture.serveDone <- capture.server.Serve(listener) }()
+	if activeSuiteLifecycle != nil && !activeSuiteLifecycle.closers.add(capture) {
+		_ = capture.Close()
+		return nil, fmt.Errorf("create OAuth callback listener after E2E watchdog cleanup started")
+	}
+	return capture, nil
+}
+
+func (c *callbackCapture) URI() string {
+	return "http://" + c.listener.Addr().String() + "/callback"
+}
+
+func (c *callbackCapture) Origin() string {
+	return "http://" + c.listener.Addr().String()
+}
+
+func (c *callbackCapture) Begin() (*callbackAttempt, error) {
+	c.mu.Lock()
+	defer c.mu.Unlock()
+	if c.closed {
+		return nil, fmt.Errorf("OAuth callback capture is closed")
+	}
+	if c.active != nil && !c.active.done {
+		return nil, fmt.Errorf("OAuth callback capture already has an active authorization")
+	}
+	attempt := &callbackAttempt{capture: c, result: make(chan oauthCallback, 1)}
+	c.active = attempt
+	return attempt, nil
+}
+
+func (c *callbackCapture) handle(w http.ResponseWriter, r *http.Request) {
+	if r.Method != http.MethodGet {
+		w.WriteHeader(http.StatusMethodNotAllowed)
+		return
+	}
+	c.mu.Lock()
+	attempt := c.active
+	if attempt == nil || attempt.done {
+		c.mu.Unlock()
+		http.Error(w, "callback not expected", http.StatusConflict)
+		return
+	}
+	attempt.count++
+	first := attempt.count == 1
+	if first {
+		query := r.URL.Query()
+		attempt.result <- oauthCallback{
+			Code:  append([]string(nil), query["code"]...),
+			State: append([]string(nil), query["state"]...),
+			Error: append([]string(nil), query["error"]...),
+		}
+	}
+	c.mu.Unlock()
+	if !first {
+		http.Error(w, "duplicate callback", http.StatusConflict)
+		return
+	}
+	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
+	w.WriteHeader(http.StatusOK)
+	_, _ = io.WriteString(w, "Authorization callback received.\n")
+}
+
+func (a *callbackAttempt) Wait(ctx context.Context) (oauthCallback, error) {
+	ctx, cancel := context.WithTimeout(ctx, callbackWaitTimeout)
+	defer cancel()
+	select {
+	case result := <-a.result:
+		return result, nil
+	case <-a.capture.closing:
+		return oauthCallback{}, fmt.Errorf("wait for OAuth callback: capture closed")
+	case <-ctx.Done():
+		return oauthCallback{}, fmt.Errorf("wait for OAuth callback: %w", ctx.Err())
+	}
+}
+
+func (a *callbackAttempt) Finish(ctx context.Context) error {
+	quiet := time.NewTimer(100 * time.Millisecond)
+	defer quiet.Stop()
+	select {
+	case <-quiet.C:
+	case <-ctx.Done():
+		return fmt.Errorf("confirm OAuth callback cardinality: %w", ctx.Err())
+	}
+	a.capture.mu.Lock()
+	defer a.capture.mu.Unlock()
+	if a.capture.active != a {
+		return fmt.Errorf("OAuth callback attempt is no longer active")
+	}
+	a.done = true
+	if a.count != 1 {
+		return fmt.Errorf("OAuth callback cardinality was %d, want exactly one", a.count)
+	}
+	return nil
+}
+
+func validateOAuthCallback(callback oauthCallback, expectedState string) (string, error) {
+	if len(callback.Error) != 0 {
+		return "", fmt.Errorf("OAuth callback contained an error")
+	}
+	if len(callback.State) != 1 || callback.State[0] != expectedState {
+		return "", fmt.Errorf("OAuth callback state did not match exactly")
+	}
+	if len(callback.Code) != 1 || callback.Code[0] == "" {
+		return "", fmt.Errorf("OAuth callback did not contain exactly one non-empty code")
+	}
+	return callback.Code[0], nil
+}
+
+func (c *callbackCapture) Close() error {
+	if c == nil {
+		return nil
+	}
+	if activeSuiteLifecycle != nil {
+		defer activeSuiteLifecycle.closers.remove(c)
+	}
+	c.closeOnce.Do(func() {
+		c.mu.Lock()
+		c.closed = true
+		close(c.closing)
+		c.mu.Unlock()
+
+		timeout := c.closeTimeout
+		if timeout <= 0 {
+			timeout = callbackCloseTimeout
+		}
+		ctx, cancel := context.WithTimeout(context.Background(), timeout)
+		defer cancel()
+		shutdownErr := c.server.Shutdown(ctx)
+
+		var serveErr error
+		select {
+		case serveErr = <-c.serveDone:
+		case <-ctx.Done():
+			if shutdownErr != nil {
+				c.closeErr = fmt.Errorf("close OAuth callback: %w", shutdownErr)
+			} else {
+				c.closeErr = fmt.Errorf("close OAuth callback: %w", ctx.Err())
+			}
+			return
+		}
+		if serveErr != nil && !errors.Is(serveErr, http.ErrServerClosed) {
+			c.closeErr = fmt.Errorf("serve OAuth callback: %w", serveErr)
+			return
+		}
+		if shutdownErr != nil {
+			c.closeErr = fmt.Errorf("close OAuth callback: %w", shutdownErr)
+		}
+	})
+	return c.closeErr
+}
diff --git a/core/auth/ui/e2e/oauth_helpers_test.go b/core/auth/ui/e2e/oauth_helpers_test.go
new file mode 100644
index 0000000..5f62b6f
--- /dev/null
+++ b/core/auth/ui/e2e/oauth_helpers_test.go
@@ -0,0 +1,388 @@
+package e2e
+
+import (
+	"context"
+	"encoding/base64"
+	"encoding/json"
+	"fmt"
+	"net/http"
+	"net/http/httptest"
+	"net/url"
+	"os"
+	"path/filepath"
+	"strings"
+	"sync"
+	"testing"
+	"time"
+)
+
+func TestHydraClientCreationAndBasicAuthTokenExchange(t *testing.T) {
+	const (
+		clientID     = "generated-client"
+		clientSecret = "generated-client-secret"
+		code         = "generated-authorization-code"
+		redirectURI  = "http://127.0.0.1:43210/callback"
+	)
+	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		switch r.URL.Path {
+		case "/admin/clients":
+			if r.Method != http.MethodPost || r.Header.Get("Content-Type") != "application/json" {
+				t.Errorf("unexpected client request method or content type")
+			}
+			var request hydraOAuthClient
+			if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
+				t.Errorf("decode client request: %v", err)
+			}
+			if request.ClientID != clientID || request.ClientSecret != clientSecret || len(request.RedirectURIs) != 1 || request.RedirectURIs[0] != redirectURI || request.TokenEndpointAuthMethod != "client_secret_basic" {
+				t.Error("Hydra client request did not preserve the confidential-client contract")
+			}
+			w.Header().Set("Content-Type", "application/json")
+			w.WriteHeader(http.StatusCreated)
+			_ = json.NewEncoder(w).Encode(request)
+		case "/oauth2/token":
+			gotID, gotSecret, ok := r.BasicAuth()
+			if !ok || gotID != clientID || gotSecret != clientSecret {
+				t.Error("token exchange did not use HTTP Basic client authentication")
+			}
+			if err := r.ParseForm(); err != nil {
+				t.Errorf("parse token form: %v", err)
+			}
+			if r.Form.Get("grant_type") != "authorization_code" || r.Form.Get("code") != code || r.Form.Get("redirect_uri") != redirectURI {
+				t.Error("token exchange form did not preserve the authorization-code contract")
+			}
+			w.Header().Set("Content-Type", "application/json")
+			fmt.Fprint(w, `{"access_token":"access","id_token":"header.payload.signature","token_type":"bearer"}`)
+		default:
+			http.NotFound(w, r)
+		}
+	}))
+	defer server.Close()
+
+	client := newDirectAPIClient(server.URL, server.URL)
+	defer client.close()
+	requested := hydraOAuthClient{
+		ClientID: clientID, ClientSecret: clientSecret, RedirectURIs: []string{redirectURI},
+		GrantTypes: []string{"authorization_code"}, ResponseTypes: []string{"code"}, Scope: "openid", TokenEndpointAuthMethod: "client_secret_basic",
+	}
+	created, err := client.createHydraOAuthClient(context.Background(), server.URL, requested)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if created.ClientID != clientID {
+		t.Fatal("created Hydra client id did not match")
+	}
+	status, tokens, oauthErr, err := client.exchangeHydraAuthorizationCode(context.Background(), server.URL, clientID, clientSecret, redirectURI, code)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if status != http.StatusOK || tokens.AccessToken == "" || tokens.IDToken == "" || tokens.TokenType != "bearer" || oauthErr.Error != "" {
+		t.Fatal("unexpected successful token response")
+	}
+}
+
+func TestHydraTokenErrorIsBoundedAndSanitized(t *testing.T) {
+	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
+		w.Header().Set("Content-Type", "application/json")
+		w.WriteHeader(http.StatusBadRequest)
+		fmt.Fprint(w, `{"error":"invalid_grant","error_description":"generated-authorization-code"}`)
+	}))
+	defer server.Close()
+	client := newDirectAPIClient(server.URL, server.URL)
+	defer client.close()
+
+	status, _, oauthErr, err := client.exchangeHydraAuthorizationCode(context.Background(), server.URL, "client", "secret", "http://127.0.0.1/callback", "generated-authorization-code")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if status != http.StatusBadRequest || oauthErr.Error != "invalid_grant" {
+		t.Fatalf("unexpected OAuth error status=%d code=%q", status, oauthErr.Error)
+	}
+	if got := sanitizedOAuthErrorCode("generated-secret-value"); got != "invalid_response" {
+		t.Fatalf("unsafe OAuth error code was retained: %q", got)
+	}
+}
+
+func TestDecodeJWTPayloadUnverifiedAndAudience(t *testing.T) {
+	payload, err := json.Marshal(map[string]any{
+		"sub": "generated-user", "username": "generated-user", "email": "generated-user@example.test",
+		"iss": "http://127.0.0.1:4444/", "aud": []string{"generated-client", "other-client"}, "nonce": "generated-nonce",
+	})
+	if err != nil {
+		t.Fatal(err)
+	}
+	token := base64.RawURLEncoding.EncodeToString([]byte(`{"alg":"none"}`)) + "." + base64.RawURLEncoding.EncodeToString(payload) + ".unsigned"
+	claims, err := decodeJWTPayloadUnverified(token)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if subject, ok := jwtStringClaim(claims, "sub"); !ok || subject != "generated-user" {
+		t.Fatal("JWT string claim was not decoded")
+	}
+	if !jwtAudienceContains(claims, "generated-client") || jwtAudienceContains(claims, "missing-client") {
+		t.Fatal("JWT audience membership was incorrect")
+	}
+	claims["aud"] = "single-client"
+	if !jwtAudienceContains(claims, "single-client") {
+		t.Fatal("JWT string audience was not accepted")
+	}
+}
+
+func TestDecodeJWTPayloadUnverifiedRejectsMalformedAndOversized(t *testing.T) {
+	invalid := []string{
+		"not-a-jwt",
+		"header.%%%.signature",
+		"header." + base64.RawURLEncoding.EncodeToString([]byte("[]")) + ".signature",
+		"header." + base64.RawURLEncoding.EncodeToString([]byte("not-json")) + ".signature",
+		"header." + strings.Repeat("a", base64.RawURLEncoding.EncodedLen(maxJWTPayload)+1) + ".signature",
+	}
+	for _, token := range invalid {
+		if _, err := decodeJWTPayloadUnverified(token); err == nil {
+			t.Fatal("malformed or oversized JWT payload was accepted")
+		}
+	}
+}
+
+func TestCallbackCaptureSuccessDuplicateAndRearm(t *testing.T) {
+	capture, err := startCallbackCapture()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer capture.Close()
+	client := &http.Client{Timeout: time.Second}
+	defer client.CloseIdleConnections()
+	attempt, err := capture.Begin()
+	if err != nil {
+		t.Fatal(err)
+	}
+	values := url.Values{"code": {"generated-code"}, "state": {"generated-state"}}
+	response, err := client.Get(capture.URI() + "?" + values.Encode())
+	if err != nil {
+		t.Fatal(err)
+	}
+	_ = response.Body.Close()
+	callback, err := attempt.Wait(context.Background())
+	if err != nil {
+		t.Fatal(err)
+	}
+	if _, err := validateOAuthCallback(callback, "generated-state"); err != nil {
+		t.Fatal(err)
+	}
+	duplicate, err := client.Get(capture.URI() + "?" + values.Encode())
+	if err != nil {
+		t.Fatal(err)
+	}
+	_ = duplicate.Body.Close()
+	if duplicate.StatusCode != http.StatusConflict {
+		t.Fatalf("duplicate callback status=%d, want 409", duplicate.StatusCode)
+	}
+	if err := attempt.Finish(context.Background()); err == nil || !strings.Contains(err.Error(), "cardinality") {
+		t.Fatalf("duplicate callback cardinality error=%v", err)
+	}
+
+	second, err := capture.Begin()
+	if err != nil {
+		t.Fatal(err)
+	}
+	response, err = client.Get(capture.URI() + "?code=second-code&state=second-state")
+	if err != nil {
+		t.Fatal(err)
+	}
+	_ = response.Body.Close()
+	if _, err := second.Wait(context.Background()); err != nil {
+		t.Fatal(err)
+	}
+	if err := second.Finish(context.Background()); err != nil {
+		t.Fatal(err)
+	}
+}
+
+func TestCallbackCaptureTimeoutCancellationAndValidation(t *testing.T) {
+	capture, err := startCallbackCapture()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer capture.Close()
+	attempt, err := capture.Begin()
+	if err != nil {
+		t.Fatal(err)
+	}
+	ctx, cancel := context.WithTimeout(context.Background(), 20*time.Millisecond)
+	defer cancel()
+	if _, err := attempt.Wait(ctx); err == nil || !strings.Contains(err.Error(), "deadline exceeded") {
+		t.Fatalf("callback timeout error=%v", err)
+	}
+
+	cancelCapture, err := startCallbackCapture()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer cancelCapture.Close()
+	cancelAttempt, err := cancelCapture.Begin()
+	if err != nil {
+		t.Fatal(err)
+	}
+	canceled, cancelNow := context.WithCancel(context.Background())
+	cancelNow()
+	if _, err := cancelAttempt.Wait(canceled); err == nil || !strings.Contains(err.Error(), "context canceled") {
+		t.Fatalf("callback cancellation error=%v", err)
+	}
+
+	for _, callback := range []oauthCallback{
+		{Error: []string{"access_denied"}, State: []string{"state"}},
+		{Code: []string{"code"}, State: []string{"wrong"}},
+		{Code: []string{"one", "two"}, State: []string{"state"}},
+		{Code: []string{"code"}, State: []string{"state", "state"}},
+	} {
+		if _, err := validateOAuthCallback(callback, "state"); err == nil {
+			t.Fatal("invalid OAuth callback was accepted")
+		}
+	}
+}
+
+func TestCallbackCaptureCloseIdempotentAndBeginAfterClose(t *testing.T) {
+	capture, err := startCallbackCapture()
+	if err != nil {
+		t.Fatal(err)
+	}
+	if err := capture.Close(); err != nil {
+		t.Fatal(err)
+	}
+	if err := capture.Close(); err != nil {
+		t.Fatalf("idempotent second close: %v", err)
+	}
+	if _, err := capture.Begin(); err == nil || !strings.Contains(err.Error(), "closed") {
+		t.Fatalf("Begin after close error=%v", err)
+	}
+}
+
+func TestCallbackCaptureCloseReleasesActiveWait(t *testing.T) {
+	capture, err := startCallbackCapture()
+	if err != nil {
+		t.Fatal(err)
+	}
+	attempt, err := capture.Begin()
+	if err != nil {
+		t.Fatal(err)
+	}
+	waitDone := make(chan error, 1)
+	go func() {
+		_, err := attempt.Wait(context.Background())
+		waitDone <- err
+	}()
+	if err := capture.Close(); err != nil {
+		t.Fatal(err)
+	}
+	select {
+	case err := <-waitDone:
+		if err == nil || !strings.Contains(err.Error(), "capture closed") {
+			t.Fatalf("active callback wait close error=%v", err)
+		}
+	case <-time.After(time.Second):
+		t.Fatal("active callback wait was not released by close")
+	}
+}
+
+func TestCallbackCaptureCloseBoundsMissingServeCompletion(t *testing.T) {
+	capture := &callbackCapture{
+		server:       &http.Server{},
+		serveDone:    make(chan error),
+		closing:      make(chan struct{}),
+		closeTimeout: 20 * time.Millisecond,
+	}
+	started := time.Now()
+	err := capture.Close()
+	if err == nil || !strings.Contains(err.Error(), "deadline exceeded") {
+		t.Fatalf("bounded close error=%v", err)
+	}
+	if elapsed := time.Since(started); elapsed > 500*time.Millisecond {
+		t.Fatalf("bounded close took %s", elapsed)
+	}
+	if second := capture.Close(); second == nil || second.Error() != err.Error() {
+		t.Fatalf("idempotent failed close=%v, want %v", second, err)
+	}
+}
+
+func TestCallbackCaptureConcurrentDuplicates(t *testing.T) {
+	capture, err := startCallbackCapture()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer capture.Close()
+	attempt, err := capture.Begin()
+	if err != nil {
+		t.Fatal(err)
+	}
+	const requests = 8
+	client := &http.Client{Timeout: time.Second}
+	defer client.CloseIdleConnections()
+	start := make(chan struct{})
+	statuses := make(chan int, requests)
+	errors := make(chan error, requests)
+	var workers sync.WaitGroup
+	for range requests {
+		workers.Add(1)
+		go func() {
+			defer workers.Done()
+			<-start
+			response, err := client.Get(capture.URI() + "?code=generated-code&state=generated-state")
+			if err != nil {
+				errors <- err
+				return
+			}
+			_ = response.Body.Close()
+			statuses <- response.StatusCode
+		}()
+	}
+	close(start)
+	workers.Wait()
+	close(statuses)
+	close(errors)
+	for err := range errors {
+		t.Errorf("concurrent callback request: %v", err)
+	}
+	ok, conflicts := 0, 0
+	for status := range statuses {
+		switch status {
+		case http.StatusOK:
+			ok++
+		case http.StatusConflict:
+			conflicts++
+		default:
+			t.Errorf("concurrent callback status=%d", status)
+		}
+	}
+	if ok != 1 || conflicts != requests-1 {
+		t.Fatalf("concurrent callback statuses: ok=%d conflicts=%d", ok, conflicts)
+	}
+	if _, err := attempt.Wait(context.Background()); err != nil {
+		t.Fatal(err)
+	}
+	if err := attempt.Finish(context.Background()); err == nil || !strings.Contains(err.Error(), "cardinality") {
+		t.Fatalf("concurrent duplicate cardinality error=%v", err)
+	}
+}
+
+func TestFinalMakeTargetsRemainOptIn(t *testing.T) {
+	repo, err := repositoryDir()
+	if err != nil {
+		t.Fatal(err)
+	}
+	data, err := os.ReadFile(filepath.Join(repo, "Makefile"))
+	if err != nil {
+		t.Fatal(err)
+	}
+	makefile := string(data)
+	for _, required := range []string{
+		"test:\n\tgo test ./...\n\tgo vet ./...",
+		"test-e2e:\n\tgo test -tags=e2e -count=1 -timeout=10m -v ./e2e",
+		"test-e2e-offline:\n\tAUTH_UI_E2E_OFFLINE=1 go test -tags=e2e -count=1 -timeout=10m -v ./e2e",
+		"clean-e2e-artifacts:\n\trm -rf -- e2e/artifacts",
+	} {
+		if !strings.Contains(makefile, required) {
+			t.Fatalf("Makefile omitted required opt-in target contract %q", required)
+		}
+	}
+	if strings.Contains(makefile, "test: test-e2e") || strings.Contains(makefile, "clean: clean-e2e-artifacts") {
+		t.Fatal("Makefile made an ordinary or offline target depend on an online/destructive E2E target")
+	}
+}
diff --git a/core/auth/ui/e2e/process.go b/core/auth/ui/e2e/process.go
new file mode 100644
index 0000000..2de96de
--- /dev/null
+++ b/core/auth/ui/e2e/process.go
@@ -0,0 +1,222 @@
+package e2e
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"io"
+	"net"
+	"net/http"
+	"os"
+	"os/exec"
+	"strings"
+	"sync"
+	"time"
+)
+
+type processSignal int
+
+const (
+	processTerminate processSignal = iota
+	processKill
+)
+
+type supervisedProcess struct {
+	name       string
+	cmd        *exec.Cmd
+	logPath    string
+	logFile    *os.File
+	pgid       int
+	completed  chan struct{}
+	resultMu   sync.RWMutex
+	result     error
+	stop       sync.Once
+	stopErr    error
+	redactions []string
+}
+
+func startProcess(name, logPath, dir, executable string, args ...string) (*supervisedProcess, error) {
+	logFile, err := os.OpenFile(logPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0o600)
+	if err != nil {
+		return nil, err
+	}
+	cmd := exec.Command(executable, args...)
+	cmd.Dir = dir
+	cmd.Stdout = logFile
+	cmd.Stderr = logFile
+	if err := configureOwnedProcess(cmd); err != nil {
+		_ = logFile.Close()
+		return nil, fmt.Errorf("configure %s process ownership: %w", name, err)
+	}
+	if err := cmd.Start(); err != nil {
+		_ = logFile.Close()
+		return nil, fmt.Errorf("start %s: %w", name, err)
+	}
+	p := &supervisedProcess{name: name, cmd: cmd, logPath: logPath, logFile: logFile, pgid: cmd.Process.Pid, completed: make(chan struct{})}
+	go func() {
+		err := cmd.Wait()
+		_ = logFile.Close()
+		p.resultMu.Lock()
+		p.result = err
+		p.resultMu.Unlock()
+		close(p.completed)
+	}()
+	return p, nil
+}
+
+func (p *supervisedProcess) alive() bool {
+	if p == nil {
+		return false
+	}
+	select {
+	case <-p.completed:
+		return false
+	default:
+		return true
+	}
+}
+
+func (p *supervisedProcess) completion() error {
+	p.resultMu.RLock()
+	defer p.resultMu.RUnlock()
+	return p.result
+}
+
+func (p *supervisedProcess) stopAndWait(timeout time.Duration) error {
+	if p == nil {
+		return nil
+	}
+	p.stop.Do(func() {
+		// Signal the group even when the leader has already exited: descendants may
+		// still own the process group and are part of this harness's ownership.
+		if err := signalOwnedProcessGroup(p.pgid, processTerminate); err != nil && !errors.Is(err, os.ErrProcessDone) {
+			p.stopErr = fmt.Errorf("terminate %s process group: %w", p.name, err)
+		}
+		deadline := time.Now().Add(timeout)
+		for ownedProcessGroupAlive(p.pgid) && time.Now().Before(deadline) {
+			time.Sleep(10 * time.Millisecond)
+		}
+		if ownedProcessGroupAlive(p.pgid) {
+			if err := signalOwnedProcessGroup(p.pgid, processKill); err != nil && !errors.Is(err, os.ErrProcessDone) && p.stopErr == nil {
+				p.stopErr = fmt.Errorf("kill %s process group: %w", p.name, err)
+			}
+		}
+
+		postKill := time.NewTimer(2 * time.Second)
+		defer postKill.Stop()
+		select {
+		case <-p.completed:
+		case <-postKill.C:
+			if p.stopErr == nil {
+				p.stopErr = fmt.Errorf("wait for %s leader after process-group kill: timeout", p.name)
+			}
+		}
+		groupDeadline := time.Now().Add(2 * time.Second)
+		for ownedProcessGroupAlive(p.pgid) && time.Now().Before(groupDeadline) {
+			time.Sleep(10 * time.Millisecond)
+		}
+		if ownedProcessGroupAlive(p.pgid) && p.stopErr == nil {
+			p.stopErr = fmt.Errorf("%s process group %d survived cleanup", p.name, p.pgid)
+		}
+		// A non-zero leader exit belongs to startup/readiness diagnostics, not
+		// cleanup. Once the owned group is gone, explicit cleanup succeeded.
+	})
+	return p.stopErr
+}
+
+func (p *supervisedProcess) exited() (bool, error) {
+	select {
+	case <-p.completed:
+		return true, p.completion()
+	default:
+		return false, nil
+	}
+}
+
+func (p *supervisedProcess) logTail(limit int64) string {
+	data, err := os.ReadFile(p.logPath)
+	if err != nil {
+		return fmt.Sprintf("<read log: %v>", err)
+	}
+	if int64(len(data)) > limit {
+		data = data[len(data)-int(limit):]
+	}
+	text := boundedText(data, int(limit))
+	for _, secret := range p.redactions {
+		if secret != "" {
+			text = strings.ReplaceAll(text, secret, "[REDACTED]")
+		}
+	}
+	return text
+}
+
+func waitHTTPReady(ctx context.Context, p *supervisedProcess, endpoints ...string) error {
+	client := &http.Client{Timeout: 750 * time.Millisecond}
+	defer client.CloseIdleConnections()
+	for {
+		allReady := true
+		for _, endpoint := range endpoints {
+			req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil)
+			if err != nil {
+				return err
+			}
+			resp, err := client.Do(req)
+			if err != nil {
+				allReady = false
+				break
+			}
+			_, _ = io.CopyN(io.Discard, resp.Body, 4096)
+			_ = resp.Body.Close()
+			if resp.StatusCode < 200 || resp.StatusCode >= 300 {
+				allReady = false
+				break
+			}
+		}
+		if allReady {
+			return nil
+		}
+		if exited, err := p.exited(); exited {
+			return fmt.Errorf("%s exited during readiness: %v\nlog tail:\n%s", p.name, err, p.logTail(8192))
+		}
+		select {
+		case <-ctx.Done():
+			return fmt.Errorf("%s readiness: %w\nlog tail:\n%s", p.name, ctx.Err(), p.logTail(8192))
+		case <-time.After(100 * time.Millisecond):
+		}
+	}
+}
+
+func waitTCPReady(ctx context.Context, p *supervisedProcess, addresses ...string) error {
+	pending := append([]string(nil), addresses...)
+	for len(pending) > 0 {
+		next := pending[:0]
+		for _, address := range pending {
+			conn, err := (&net.Dialer{Timeout: 500 * time.Millisecond}).DialContext(ctx, "tcp", address)
+			if err == nil {
+				_ = conn.Close()
+				continue
+			}
+			next = append(next, address)
+		}
+		pending = next
+		if len(pending) == 0 {
+			return nil
+		}
+		if exited, exitErr := p.exited(); exited {
+			return fmt.Errorf("%s exited during readiness: %v\nlog tail:\n%s", p.name, exitErr, p.logTail(8192))
+		}
+		select {
+		case <-ctx.Done():
+			return fmt.Errorf("%s readiness for %s: %w\nlog tail:\n%s", p.name, strings.Join(pending, ", "), ctx.Err(), p.logTail(8192))
+		case <-time.After(100 * time.Millisecond):
+		}
+	}
+	return nil
+}
+
+func boundedText(data []byte, limit int) string {
+	if len(data) > limit {
+		data = data[len(data)-limit:]
+	}
+	return strings.ToValidUTF8(string(data), "�")
+}
diff --git a/core/auth/ui/e2e/process_test.go b/core/auth/ui/e2e/process_test.go
new file mode 100644
index 0000000..49f7cb9
--- /dev/null
+++ b/core/auth/ui/e2e/process_test.go
@@ -0,0 +1,432 @@
+//go:build linux || darwin
+
+package e2e
+
+import (
+	"context"
+	"fmt"
+	"net/http"
+	"net/http/httptest"
+	"os"
+	"os/exec"
+	"os/signal"
+	"path/filepath"
+	"strconv"
+	"strings"
+	"sync/atomic"
+	"syscall"
+	"testing"
+	"time"
+)
+
+func TestProcessHelper(t *testing.T) {
+	if os.Getenv("AUTH_UI_E2E_PROCESS_HELPER") != "1" {
+		return
+	}
+	os.Exit(runProcessHelper())
+}
+
+func runTaggedProcessHelper() int { return runProcessHelper() }
+
+// runProcessHelper is shared by the ordinary helper test and the e2e-tagged
+// TestMain fast path. Keeping dispatch here prevents tagged helper subprocesses
+// from entering stack or browser setup before the test runner reaches this test.
+func runProcessHelper() int {
+	switch os.Getenv("AUTH_UI_E2E_PROCESS_MODE") {
+	case "exit":
+		fmt.Fprintln(os.Stderr, "helper deterministic failure marker")
+		return 23
+	case "sleep":
+		fmt.Fprintln(os.Stdout, "helper ready and sleeping")
+		for {
+			time.Sleep(time.Second)
+		}
+	case "ignore-term":
+		signalIgnoreTerminate()
+		fmt.Fprintln(os.Stdout, "helper ignoring termination")
+		for {
+			time.Sleep(time.Second)
+		}
+	case "descendant-leader-exit":
+		cmd := exec.Command(os.Args[0], "-test.run=^TestProcessHelper$")
+		cmd.Env = append(os.Environ(), "AUTH_UI_E2E_PROCESS_MODE=ignore-term")
+		cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
+		if err := cmd.Start(); err != nil {
+			fmt.Fprintf(os.Stderr, "start descendant: %v\n", err)
+			return 25
+		}
+		fmt.Fprintf(os.Stdout, "DESCENDANT_PID=%d\n", cmd.Process.Pid)
+		return 0
+	default:
+		return 24
+	}
+}
+
+func signalIgnoreTerminate() { signal.Ignore(syscall.SIGTERM) }
+
+func helperProcessAt(t *testing.T, logPath, mode string) *supervisedProcess {
+	t.Helper()
+	oldHelper, hadHelper := os.LookupEnv("AUTH_UI_E2E_PROCESS_HELPER")
+	oldMode, hadMode := os.LookupEnv("AUTH_UI_E2E_PROCESS_MODE")
+	_ = os.Setenv("AUTH_UI_E2E_PROCESS_HELPER", "1")
+	_ = os.Setenv("AUTH_UI_E2E_PROCESS_MODE", mode)
+	p, err := startProcess("helper", logPath, "", os.Args[0], "-test.run=^TestProcessHelper$")
+	if hadHelper {
+		_ = os.Setenv("AUTH_UI_E2E_PROCESS_HELPER", oldHelper)
+	} else {
+		_ = os.Unsetenv("AUTH_UI_E2E_PROCESS_HELPER")
+	}
+	if hadMode {
+		_ = os.Setenv("AUTH_UI_E2E_PROCESS_MODE", oldMode)
+	} else {
+		_ = os.Unsetenv("AUTH_UI_E2E_PROCESS_MODE")
+	}
+	if err != nil {
+		t.Fatal(err)
+	}
+	t.Cleanup(func() {
+		if ownedProcessGroupAlive(p.pgid) {
+			if err := p.stopAndWait(time.Second); err != nil {
+				t.Errorf("cleanup helper process: %v", err)
+			}
+		}
+	})
+	return p
+}
+
+func helperProcess(t *testing.T, mode string) *supervisedProcess {
+	t.Helper()
+	return helperProcessAt(t, filepath.Join(t.TempDir(), "helper.log"), mode)
+}
+
+func TestProcessHelperDispatchBypassesTaggedSuiteSetup(t *testing.T) {
+	artifactRoot := filepath.Join(t.TempDir(), "artifacts")
+	cacheRoot := filepath.Join(t.TempDir(), "cache")
+	t.Setenv("AUTH_UI_E2E_ARTIFACT_DIR", artifactRoot)
+	t.Setenv("AUTH_UI_E2E_CACHE_DIR", cacheRoot)
+	p := helperProcess(t, "exit")
+
+	select {
+	case <-p.completed:
+	case <-time.After(3 * time.Second):
+		_ = p.stopAndWait(100 * time.Millisecond)
+		t.Fatal("helper invocation did not exit deterministically")
+	}
+	exit, ok := p.completion().(*exec.ExitError)
+	if !ok || exit.ExitCode() != 23 {
+		t.Fatalf("helper exit=%v, want status 23", p.completion())
+	}
+	if tail := p.logTail(8192); !strings.Contains(tail, "helper deterministic failure marker") || strings.Contains(tail, "E2E setup failed") {
+		t.Fatalf("unexpected helper output: %q", tail)
+	}
+	for name, path := range map[string]string{"artifact": artifactRoot, "cache": cacheRoot} {
+		if _, err := os.Stat(path); !os.IsNotExist(err) {
+			t.Fatalf("helper created %s path %s: %v", name, path, err)
+		}
+	}
+}
+
+func TestSupervisedProcessEarlyExitAndTail(t *testing.T) {
+	p := helperProcess(t, "exit")
+	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
+	defer cancel()
+	err := waitTCPReady(ctx, p, "127.0.0.1:1")
+	if err == nil || !strings.Contains(err.Error(), "exited during readiness") || !strings.Contains(err.Error(), "deterministic failure marker") {
+		t.Fatalf("error=%v", err)
+	}
+	for i := 0; i < 10; i++ {
+		if exited, got := p.exited(); !exited || got == nil {
+			t.Fatalf("completion read %d: exited=%v error=%v", i, exited, got)
+		}
+	}
+}
+
+func TestReadinessTimeoutIncludesBoundedTail(t *testing.T) {
+	p := helperProcess(t, "sleep")
+	defer p.stopAndWait(time.Second)
+	ctx, cancel := context.WithTimeout(context.Background(), 150*time.Millisecond)
+	defer cancel()
+	err := waitTCPReady(ctx, p, "127.0.0.1:1")
+	if err == nil || !strings.Contains(err.Error(), "deadline exceeded") || !strings.Contains(err.Error(), "helper ready") {
+		t.Fatalf("error=%v", err)
+	}
+}
+
+func TestHTTPReadiness(t *testing.T) {
+	p := helperProcess(t, "sleep")
+	defer p.stopAndWait(time.Second)
+	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNoContent) }))
+	defer server.Close()
+	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
+	defer cancel()
+	if err := waitHTTPReady(ctx, p, server.URL); err != nil {
+		t.Fatal(err)
+	}
+}
+
+func TestEmergencyTerminationKillsKnownGroupAndDescendants(t *testing.T) {
+	p := helperProcessAt(t, filepath.Join(t.TempDir(), "emergency.log"), "ignore-term")
+	if err := emergencyTerminateOwnedProcesses(p.cmd.Process.Pid, []int{p.pgid}); err != nil {
+		t.Fatal(err)
+	}
+	select {
+	case <-p.completed:
+	case <-time.After(2 * time.Second):
+		t.Fatal("emergency termination did not reap helper leader")
+	}
+	if ownedProcessGroupAlive(p.pgid) {
+		t.Fatal("emergency termination left known process group alive")
+	}
+}
+
+func TestSupervisedProcessStopIsIdempotent(t *testing.T) {
+	p := helperProcess(t, "sleep")
+	if err := p.stopAndWait(time.Second); err != nil {
+		t.Fatal(err)
+	}
+	if err := p.stopAndWait(time.Second); err != nil {
+		t.Fatal(err)
+	}
+	if p.alive() || ownedProcessGroupAlive(p.pgid) {
+		t.Fatal("stopped process or group is alive")
+	}
+}
+
+func TestSupervisedProcessForceKillsIgnoringLeader(t *testing.T) {
+	p := helperProcess(t, "ignore-term")
+	waitForLog(t, p.logPath, "helper ignoring termination")
+	started := time.Now()
+	if err := p.stopAndWait(100 * time.Millisecond); err != nil {
+		t.Fatal(err)
+	}
+	if elapsed := time.Since(started); elapsed > 3*time.Second {
+		t.Fatalf("force cleanup exceeded bound: %s", elapsed)
+	}
+	if ownedProcessGroupAlive(p.pgid) {
+		t.Fatal("force-killed process group is alive")
+	}
+}
+
+func TestSupervisedProcessCleansDescendantAfterLeaderExit(t *testing.T) {
+	p := helperProcess(t, "descendant-leader-exit")
+	pidText := waitForLogValue(t, p.logPath, "DESCENDANT_PID=")
+	pid, err := strconv.Atoi(pidText)
+	if err != nil {
+		t.Fatal(err)
+	}
+	select {
+	case <-p.completed:
+	case <-time.After(3 * time.Second):
+		t.Fatal("leader did not exit")
+	}
+	if !ownedProcessGroupAlive(p.pgid) {
+		t.Fatal("descendant process group unexpectedly absent before cleanup")
+	}
+	if err := p.stopAndWait(100 * time.Millisecond); err != nil {
+		t.Fatal(err)
+	}
+	waitForPIDGone(t, pid)
+}
+
+func TestEmergencyGroupSnapshotDoesNotBlockOnAtomicStart(t *testing.T) {
+	s := &Stack{}
+	s.ownershipMu.Lock()
+	done := make(chan []int, 1)
+	go func() { done <- s.emergencyProcessGroups() }()
+	select {
+	case groups := <-done:
+		if len(groups) != 0 {
+			t.Fatalf("busy emergency group snapshot=%v", groups)
+		}
+	case <-time.After(100 * time.Millisecond):
+		s.ownershipMu.Unlock()
+		t.Fatal("emergency group snapshot blocked on ownership lock")
+	}
+	s.ownershipMu.Unlock()
+}
+
+func TestStackCleanupWinsBeforeAtomicProcessStart(t *testing.T) {
+	var starts atomic.Int32
+	s := &Stack{startProcessOp: func(string, string, string, string, ...string) (*supervisedProcess, error) {
+		starts.Add(1)
+		return nil, fmt.Errorf("unexpected start")
+	}}
+	s.ownershipMu.Lock()
+	result := make(chan error, 1)
+	go func() {
+		_, err := s.startOwnedProcess(&s.Kratos, "kratos", "log", "dir", "binary")
+		result <- err
+	}()
+	// The proposed start is blocked immediately before its cleanupStarted check.
+	s.cleanupStarted = true
+	s.ownershipMu.Unlock()
+	if err := <-result; err == nil || !strings.Contains(err.Error(), "cleanup started before launching kratos") {
+		t.Fatalf("atomic start error=%v", err)
+	}
+	if starts.Load() != 0 || s.Kratos != nil {
+		t.Fatalf("cleanup-winning start calls=%d process=%v", starts.Load(), s.Kratos)
+	}
+}
+
+func TestAtomicProcessStartPublishesBeforeCleanupSnapshot(t *testing.T) {
+	entered, release := make(chan struct{}), make(chan struct{})
+	process := &supervisedProcess{name: "kratos", pgid: 99999999, completed: make(chan struct{})}
+	close(process.completed)
+	var stopped atomic.Int32
+	s := &Stack{
+		startProcessOp: func(string, string, string, string, ...string) (*supervisedProcess, error) {
+			close(entered)
+			<-release
+			return process, nil
+		},
+		stopProcessOp: func(got *supervisedProcess, _ time.Duration) error {
+			if got != process {
+				t.Errorf("cleanup observed process %p, want %p", got, process)
+			}
+			stopped.Add(1)
+			return nil
+		},
+	}
+	startDone := make(chan error, 1)
+	go func() {
+		_, err := s.startOwnedProcess(&s.Kratos, "kratos", "log", "dir", "binary")
+		startDone <- err
+	}()
+	<-entered
+	cleanupDone := make(chan error, 1)
+	go func() { cleanupDone <- s.StopServices() }()
+	select {
+	case <-cleanupDone:
+		t.Fatal("cleanup bypassed an in-flight atomic start")
+	case <-time.After(20 * time.Millisecond):
+	}
+	close(release)
+	if err := <-startDone; err != nil {
+		t.Fatal(err)
+	}
+	if err := <-cleanupDone; err != nil {
+		t.Fatal(err)
+	}
+	if stopped.Load() != 1 {
+		t.Fatalf("published process cleanup calls=%d", stopped.Load())
+	}
+}
+
+func TestStartupRetryAbortsAndCombinesCleanupFailure(t *testing.T) {
+	startupErr := fmt.Errorf("listen: address already in use")
+	cleanupErr := fmt.Errorf("owned group survived")
+	retry, err := startupRetryDecision(1, startupErr, cleanupErr)
+	if retry || err == nil || !strings.Contains(err.Error(), startupErr.Error()) || !strings.Contains(err.Error(), cleanupErr.Error()) {
+		t.Fatalf("retry=%v error=%v", retry, err)
+	}
+	if retry, err := startupRetryDecision(1, startupErr, nil); !retry || err != nil {
+		t.Fatalf("clean bind-conflict retry=%v error=%v", retry, err)
+	}
+}
+
+func TestStackCleanupAcceptsExitedLeaderOnceGroupIsGone(t *testing.T) {
+	p := helperProcess(t, "exit")
+	select {
+	case <-p.completed:
+	case <-time.After(3 * time.Second):
+		t.Fatal("helper did not exit")
+	}
+	s := &Stack{Kratos: p}
+	if err := s.stopProcessSet(); err != nil {
+		t.Fatalf("exited process cleanup=%v", err)
+	}
+	if s.Kratos != nil {
+		t.Fatal("confirmed-dead exited process retained ownership")
+	}
+}
+
+func TestStackRetainsProcessOwnershipUntilGroupGone(t *testing.T) {
+	p := helperProcess(t, "sleep")
+	s := &Stack{Kratos: p, stopProcessOp: func(*supervisedProcess, time.Duration) error { return nil }}
+	if err := s.stopProcessSet(); err == nil || !strings.Contains(err.Error(), "survived cleanup") {
+		t.Fatalf("cleanup error=%v", err)
+	}
+	if s.Kratos != p || !ownedProcessGroupAlive(p.pgid) {
+		t.Fatal("failed cleanup discarded ownership of a live process group")
+	}
+
+	s.stopProcessOp = nil
+	if err := s.stopProcessSet(); err != nil {
+		t.Fatal(err)
+	}
+	if s.Kratos != nil || ownedProcessGroupAlive(p.pgid) {
+		t.Fatal("confirmed-dead process group retained ownership")
+	}
+}
+
+func TestStackCloseReapsPartialStart(t *testing.T) {
+	workspace := t.TempDir()
+	artifactDir := filepath.Join(t.TempDir(), "artifacts")
+	if err := os.MkdirAll(filepath.Join(workspace, "logs"), 0o700); err != nil {
+		t.Fatal(err)
+	}
+	if err := os.MkdirAll(artifactDir, 0o700); err != nil {
+		t.Fatal(err)
+	}
+	p := helperProcessAt(t, filepath.Join(workspace, "logs", "kratos.log"), "sleep")
+	s := &Stack{Workspace: workspace, ArtifactDir: artifactDir, Kratos: p, startedAt: time.Now().UTC()}
+	if err := s.Close(false); err != nil {
+		t.Fatal(err)
+	}
+	if p.alive() || ownedProcessGroupAlive(p.pgid) {
+		t.Fatal("partial-start process survived Stack.Close")
+	}
+	if _, err := os.Stat(filepath.Join(artifactDir, "services", "kratos.log")); err != nil {
+		t.Fatalf("retained partial-start log: %v", err)
+	}
+}
+
+func TestProcessLogTailRedactsKnownSecrets(t *testing.T) {
+	path := filepath.Join(t.TempDir(), "service.log")
+	if err := os.WriteFile(path, []byte("prefix generated-secret suffix"), 0o600); err != nil {
+		t.Fatal(err)
+	}
+	p := &supervisedProcess{logPath: path, redactions: []string{"generated-secret"}}
+	got := p.logTail(1024)
+	if strings.Contains(got, "generated-secret") || !strings.Contains(got, "[REDACTED]") {
+		t.Fatalf("redacted tail=%q", got)
+	}
+}
+
+func TestBoundedText(t *testing.T) {
+	if got := boundedText([]byte("0123456789"), 4); got != "6789" {
+		t.Fatalf("got %q", got)
+	}
+}
+
+func waitForLog(t *testing.T, path, marker string) { _ = waitForLogValue(t, path, marker) }
+
+func waitForLogValue(t *testing.T, path, marker string) string {
+	t.Helper()
+	deadline := time.Now().Add(3 * time.Second)
+	for time.Now().Before(deadline) {
+		data, _ := os.ReadFile(path)
+		if index := strings.Index(string(data), marker); index >= 0 {
+			value := strings.TrimSpace(string(data[index+len(marker):]))
+			if newline := strings.IndexByte(value, '\n'); newline >= 0 {
+				value = value[:newline]
+			}
+			return value
+		}
+		time.Sleep(10 * time.Millisecond)
+	}
+	t.Fatalf("marker %q not found in %s", marker, path)
+	return ""
+}
+
+func waitForPIDGone(t *testing.T, pid int) {
+	t.Helper()
+	deadline := time.Now().Add(2 * time.Second)
+	for time.Now().Before(deadline) {
+		if err := syscall.Kill(pid, 0); err == syscall.ESRCH {
+			return
+		}
+		time.Sleep(10 * time.Millisecond)
+	}
+	t.Fatalf("PID %d survived cleanup", pid)
+}
diff --git a/core/auth/ui/e2e/process_unix.go b/core/auth/ui/e2e/process_unix.go
new file mode 100644
index 0000000..23b627e
--- /dev/null
+++ b/core/auth/ui/e2e/process_unix.go
@@ -0,0 +1,104 @@
+//go:build linux || darwin
+
+package e2e
+
+import (
+	"errors"
+	"fmt"
+	"os"
+	"os/exec"
+	"strconv"
+	"strings"
+	"syscall"
+	"time"
+)
+
+func configureOwnedProcess(cmd *exec.Cmd) error {
+	cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
+	return nil
+}
+
+func signalOwnedProcessGroup(pgid int, signal processSignal) error {
+	sig := syscall.SIGTERM
+	if signal == processKill {
+		sig = syscall.SIGKILL
+	}
+	err := syscall.Kill(-pgid, sig)
+	if errors.Is(err, syscall.ESRCH) {
+		return os.ErrProcessDone
+	}
+	return err
+}
+
+func ownedProcessGroupAlive(pgid int) bool {
+	err := syscall.Kill(-pgid, 0)
+	return err == nil || errors.Is(err, syscall.EPERM)
+}
+
+var enumerateDescendantProcessIDs = descendantProcessIDs
+
+func descendantProcessIDs(rootPID int) ([]int, error) {
+	output, err := exec.Command("ps", "-eo", "pid=,ppid=").Output()
+	if err != nil {
+		return nil, fmt.Errorf("list descendants: %w", err)
+	}
+	type relation struct{ pid, ppid int }
+	var relations []relation
+	for _, line := range strings.Split(string(output), "\n") {
+		fields := strings.Fields(line)
+		if len(fields) != 2 {
+			continue
+		}
+		pid, pidErr := strconv.Atoi(fields[0])
+		ppid, ppidErr := strconv.Atoi(fields[1])
+		if pidErr == nil && ppidErr == nil {
+			relations = append(relations, relation{pid, ppid})
+		}
+	}
+	owned := map[int]bool{rootPID: true}
+	for changed := true; changed; {
+		changed = false
+		for _, relation := range relations {
+			if owned[relation.ppid] && !owned[relation.pid] {
+				owned[relation.pid] = true
+				changed = true
+			}
+		}
+	}
+	var result []int
+	for pid := range owned {
+		if pid != rootPID {
+			result = append(result, pid)
+		}
+	}
+	return result, nil
+}
+
+// emergencyTerminateOwnedProcesses avoids Playwright/service protocols. It
+// kills every recorded service group and repeatedly snapshots direct and
+// indirect descendants of the harness before returning.
+func emergencyTerminateOwnedProcesses(rootPID int, processGroups []int) error {
+	var errs []string
+	for _, pgid := range processGroups {
+		if err := signalOwnedProcessGroup(pgid, processKill); err != nil && !errors.Is(err, os.ErrProcessDone) {
+			errs = append(errs, err.Error())
+		}
+	}
+	for attempt := 0; attempt < 3; attempt++ {
+		pids, err := enumerateDescendantProcessIDs(rootPID)
+		if err != nil {
+			errs = append(errs, err.Error())
+			break
+		}
+		for i := len(pids) - 1; i >= 0; i-- {
+			if err := syscall.Kill(pids[i], syscall.SIGKILL); err != nil && !errors.Is(err, syscall.ESRCH) {
+				errs = append(errs, fmt.Sprintf("kill descendant %d: %v", pids[i], err))
+			}
+		}
+		time.Sleep(25 * time.Millisecond)
+	}
+	if len(errs) > 0 {
+		return fmt.Errorf("emergency process cleanup: %s", strings.Join(errs, "; "))
+	}
+	return nil
+}
diff --git a/core/auth/ui/e2e/process_unsupported.go b/core/auth/ui/e2e/process_unsupported.go
new file mode 100644
index 0000000..cbdbada
--- /dev/null
+++ b/core/auth/ui/e2e/process_unsupported.go
@@ -0,0 +1,24 @@
+//go:build !linux && !darwin
+
+package e2e
+
+import (
+	"fmt"
+	"os/exec"
+)
+
+func configureOwnedProcess(_ *exec.Cmd) error {
+	return fmt.Errorf("unsupported E2E process platform")
+}
+
+func signalOwnedProcessGroup(_ int, _ processSignal) error { return nil }
+func ownedProcessGroupAlive(_ int) bool                    { return false }
+
+var enumerateDescendantProcessIDs = descendantProcessIDs
+
+func descendantProcessIDs(_ int) ([]int, error) {
+	return nil, fmt.Errorf("unsupported E2E process platform")
+}
+func emergencyTerminateOwnedProcesses(_ int, _ []int) error {
+	return fmt.Errorf("unsupported E2E process platform")
+}
diff --git a/core/auth/ui/e2e/process_unsupported_test.go b/core/auth/ui/e2e/process_unsupported_test.go
new file mode 100644
index 0000000..14bc5cc
--- /dev/null
+++ b/core/auth/ui/e2e/process_unsupported_test.go
@@ -0,0 +1,23 @@
+//go:build !linux && !darwin
+
+package e2e
+
+import (
+	"os"
+	"path/filepath"
+	"runtime"
+	"strings"
+	"testing"
+)
+
+func runTaggedProcessHelper() int { return 24 }
+
+func TestUnsupportedPlatformRejectsBeforeProcessStart(t *testing.T) {
+	if _, err := artifactsFor(runtime.GOOS, runtime.GOARCH); err == nil || !strings.Contains(err.Error(), "unsupported E2E platform") {
+		t.Fatalf("platform rejection error=%v", err)
+	}
+	_, err := startProcess("unsupported", filepath.Join(t.TempDir(), "process.log"), "", os.Args[0])
+	if err == nil || !strings.Contains(err.Error(), "unsupported E2E process platform") {
+		t.Fatalf("process rejection error=%v", err)
+	}
+}
diff --git a/core/auth/ui/e2e/stack.go b/core/auth/ui/e2e/stack.go
new file mode 100644
index 0000000..9bf17fa
--- /dev/null
+++ b/core/auth/ui/e2e/stack.go
@@ -0,0 +1,517 @@
+package e2e
+
+import (
+	"context"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"io"
+	"net"
+	"net/http"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"runtime"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+)
+
+type stackPorts struct {
+	KratosPublic int `json:"kratos_public"`
+	KratosAdmin  int `json:"kratos_admin"`
+	HydraPublic  int `json:"hydra_public"`
+	HydraAdmin   int `json:"hydra_admin"`
+	UI           int `json:"ui"`
+	API          int `json:"api"`
+	SMTP         int `json:"smtp"`
+}
+
+type Stack struct {
+	Repo           string
+	Workspace      string
+	ArtifactDir    string
+	Ports          stackPorts
+	KratosURL      string
+	KratosAdmin    string
+	HydraURL       string
+	HydraAdmin     string
+	UIURL          string
+	APIURL         string
+	Kratos         *supervisedProcess
+	Hydra          *supervisedProcess
+	AuthUI         *supervisedProcess
+	startedAt      time.Time
+	ready          bool
+	lastStatus     string
+	metadataMu     sync.Mutex
+	redactions     []string
+	ownershipMu    sync.Mutex
+	cleanupStarted bool
+	stopOnce       sync.Once
+	stopErr        error
+	startProcessOp func(string, string, string, string, ...string) (*supervisedProcess, error)
+	stopProcessOp  func(*supervisedProcess, time.Duration) error
+}
+
+func startStack() (*Stack, error) {
+	return startStackOwned(nil)
+}
+
+func startStackOwned(owner *suiteLifecycle) (*Stack, error) {
+	if _, err := artifactsFor(runtime.GOOS, runtime.GOARCH); err != nil {
+		return nil, err
+	}
+	repo, err := repositoryDir()
+	if err != nil {
+		return nil, err
+	}
+	workspace, err := os.MkdirTemp("", "auth-ui-e2e-*")
+	if err != nil {
+		return nil, err
+	}
+	runDir, err := createRunArtifactDir(repo)
+	if err != nil {
+		_ = os.RemoveAll(workspace)
+		return nil, err
+	}
+	s := &Stack{Repo: repo, Workspace: workspace, ArtifactDir: runDir, startedAt: time.Now().UTC()}
+	if owner != nil && !owner.setStack(s) {
+		_ = s.Close(false)
+		return s, fmt.Errorf("E2E watchdog fired before stack ownership registration")
+	}
+	if err := s.prepare(); err != nil {
+		s.recordRun("setup_failed", err)
+		return s, fmt.Errorf("prepare E2E stack: %w", err)
+	}
+	for attempt := 1; attempt <= 3; attempt++ {
+		err = s.startAttempt()
+		if err == nil {
+			s.metadataMu.Lock()
+			s.ready = true
+			s.metadataMu.Unlock()
+			s.recordRun("ready", nil)
+			return s, nil
+		}
+		cleanupErr := s.stopProcessSet()
+		retry, attemptErr := startupRetryDecision(attempt, err, cleanupErr)
+		if !retry {
+			s.recordRun("setup_failed", attemptErr)
+			return s, attemptErr
+		}
+	}
+	return s, err
+}
+
+func (s *Stack) prepare() error {
+	for _, dir := range []string{"bin", "config", "logs"} {
+		if err := os.MkdirAll(filepath.Join(s.Workspace, dir), 0o700); err != nil {
+			return err
+		}
+	}
+	platform, _ := artifactsFor(runtime.GOOS, runtime.GOARCH)
+	offline := os.Getenv("AUTH_UI_E2E_OFFLINE") == "1"
+	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Minute)
+	defer cancel()
+	for _, artifact := range []releaseArtifact{platform.Kratos, platform.Hydra} {
+		archivePath, err := ensureArchive(ctx, downloadClient(), cacheRoot(s.Repo), artifact, offline)
+		if err != nil {
+			return err
+		}
+		binary, err := extractBinary(archivePath, filepath.Join(s.Workspace, "bin"), artifact.Service)
+		if err != nil {
+			return err
+		}
+		if err := verifyBinaryVersion(binary, artifact.Version); err != nil {
+			return err
+		}
+	}
+	ctx, cancel = context.WithTimeout(context.Background(), 2*time.Minute)
+	defer cancel()
+	cmd := exec.CommandContext(ctx, "go", "build", "-o", filepath.Join(s.Workspace, "bin", "auth-ui"), ".")
+	cmd.Dir = s.Repo
+	output, err := cmd.CombinedOutput()
+	if ctx.Err() != nil {
+		return fmt.Errorf("build auth-ui: %w", ctx.Err())
+	}
+	if err != nil {
+		return fmt.Errorf("build auth-ui: %w: %s", err, boundedText(output, 8192))
+	}
+	return nil
+}
+
+func (s *Stack) startAttempt() error {
+	reservations, ports, err := reservePorts(7)
+	if err != nil {
+		return err
+	}
+	defer func() {
+		for _, reservation := range reservations {
+			_ = reservation.Close()
+		}
+	}()
+	s.metadataMu.Lock()
+	s.Ports = stackPorts{ports[0], ports[1], ports[2], ports[3], ports[4], ports[5], ports[6]}
+	s.KratosURL = loopbackURL(s.Ports.KratosPublic)
+	s.KratosAdmin = loopbackURL(s.Ports.KratosAdmin)
+	s.HydraURL = loopbackURL(s.Ports.HydraPublic)
+	s.HydraAdmin = loopbackURL(s.Ports.HydraAdmin)
+	s.UIURL = loopbackURL(s.Ports.UI)
+	s.APIURL = loopbackURL(s.Ports.API)
+	s.metadataMu.Unlock()
+	cookie, err := randomSecret(16)
+	if err != nil {
+		return err
+	}
+	cipher, err := randomSecret(16)
+	if err != nil {
+		return err
+	}
+	hydra, err := randomSecret(32)
+	if err != nil {
+		return err
+	}
+	s.metadataMu.Lock()
+	s.redactions = []string{cookie, cipher, hydra}
+	s.metadataMu.Unlock()
+	values := fixtureValues{
+		KratosPublicURL: s.KratosURL, KratosAdminURL: s.KratosAdmin,
+		KratosPublicPort: s.Ports.KratosPublic, KratosAdminPort: s.Ports.KratosAdmin,
+		HydraPublicURL: s.HydraURL, HydraAdminURL: s.HydraAdmin,
+		HydraPublicPort: s.Ports.HydraPublic, HydraAdminPort: s.Ports.HydraAdmin,
+		UIURL: s.UIURL, SMTPPort: s.Ports.SMTP,
+		CookieSecret: cookie, CipherSecret: cipher, HydraSecret: hydra,
+	}
+	if err := renderFixtures(s.Repo, filepath.Join(s.Workspace, "config"), values); err != nil {
+		return err
+	}
+	_ = reservations[6].Close() // No courier is started; only a valid unused SMTP address is needed.
+
+	_ = reservations[0].Close()
+	_ = reservations[1].Close()
+	process, err := s.startOwnedProcess(&s.Kratos, "kratos", s.logPath("kratos"), s.Workspace, s.binary("kratos"), "serve", "-c", s.config("kratos.yml"), "--dev", "--sqa-opt-out")
+	if err != nil {
+		return err
+	}
+	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
+	err = waitHTTPReady(ctx, process, s.KratosURL+"/health/ready", s.KratosAdmin+"/health/ready")
+	cancel()
+	if err != nil {
+		return err
+	}
+
+	_ = reservations[2].Close()
+	_ = reservations[3].Close()
+	process, err = s.startOwnedProcess(&s.Hydra, "hydra", s.logPath("hydra"), s.Workspace, s.binary("hydra"), "serve", "-c", s.config("hydra.yml"), "all", "--dev", "--sqa-opt-out")
+	if err != nil {
+		return err
+	}
+	ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second)
+	err = waitHTTPReady(ctx, process, s.HydraURL+"/health/ready", s.HydraAdmin+"/health/ready")
+	cancel()
+	if err != nil {
+		return err
+	}
+
+	args := []string{"-port", strconv.Itoa(s.Ports.UI), "-api-port", strconv.Itoa(s.Ports.API), "-kratos", s.KratosURL, "-kratos-api", s.KratosAdmin, "-hydra", "127.0.0.1:" + strconv.Itoa(s.Ports.HydraAdmin), "-enable-registration=true", "-email-domain=example.test"}
+	_ = reservations[4].Close()
+	_ = reservations[5].Close()
+	process, err = s.startOwnedProcess(&s.AuthUI, "auth-ui", s.logPath("auth-ui"), s.Repo, s.binary("auth-ui"), args...)
+	if err != nil {
+		return err
+	}
+	ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second)
+	err = waitTCPReady(ctx, process,
+		"127.0.0.1:"+strconv.Itoa(s.Ports.UI),
+		"127.0.0.1:"+strconv.Itoa(s.Ports.API),
+	)
+	cancel()
+	return err
+}
+
+func reservePorts(count int) ([]net.Listener, []int, error) {
+	listeners := make([]net.Listener, 0, count)
+	ports := make([]int, 0, count)
+	for len(ports) < count {
+		listener, err := net.Listen("tcp", "127.0.0.1:0")
+		if err != nil {
+			for _, reserved := range listeners {
+				_ = reserved.Close()
+			}
+			return nil, nil, err
+		}
+		listeners = append(listeners, listener)
+		ports = append(ports, listener.Addr().(*net.TCPAddr).Port)
+	}
+	return listeners, ports, nil
+}
+
+func loopbackURL(port int) string           { return "http://127.0.0.1:" + strconv.Itoa(port) }
+func (s *Stack) binary(name string) string  { return filepath.Join(s.Workspace, "bin", name) }
+func (s *Stack) config(name string) string  { return filepath.Join(s.Workspace, "config", name) }
+func (s *Stack) logPath(name string) string { return filepath.Join(s.Workspace, "logs", name+".log") }
+
+func isBindConflict(err error) bool {
+	text := strings.ToLower(err.Error())
+	return strings.Contains(text, "address already in use") || strings.Contains(text, "address in use")
+}
+
+func startupRetryDecision(attempt int, startupErr, cleanupErr error) (bool, error) {
+	if cleanupErr != nil {
+		return false, fmt.Errorf("startup attempt %d failed: %v; retry cleanup failed: %w", attempt, startupErr, cleanupErr)
+	}
+	if !isBindConflict(startupErr) || attempt >= 3 {
+		return false, startupErr
+	}
+	return true, nil
+}
+
+func (s *Stack) startOwnedProcess(slot **supervisedProcess, name, logPath, dir, executable string, args ...string) (*supervisedProcess, error) {
+	// Cleanup and process creation share this lock from the terminal-state check
+	// through cmd.Start and slot publication. StopServices can therefore either
+	// prevent the spawn or observe the complete ownership; it cannot snapshot a
+	// nil slot while a process is being created.
+	s.ownershipMu.Lock()
+	defer s.ownershipMu.Unlock()
+	if s.cleanupStarted {
+		return nil, fmt.Errorf("E2E cleanup started before launching %s", name)
+	}
+	start := s.startProcessOp
+	if start == nil {
+		start = startProcess
+	}
+	process, err := start(name, logPath, dir, executable, args...)
+	if err != nil {
+		return process, err
+	}
+	if process == nil {
+		return nil, fmt.Errorf("started %s process ownership is unavailable", name)
+	}
+	process.redactions = append([]string(nil), s.redactions...)
+	*slot = process
+	return process, nil
+}
+
+func (s *Stack) ownedProcessGroups() []int {
+	if s == nil {
+		return nil
+	}
+	s.ownershipMu.Lock()
+	defer s.ownershipMu.Unlock()
+	return s.ownedProcessGroupsLocked()
+}
+
+func (s *Stack) emergencyProcessGroups() []int {
+	if s == nil || !s.ownershipMu.TryLock() {
+		// Descendant discovery remains available when an OS start is holding the
+		// ownership lock, so emergency exit must never block on this mutex.
+		return nil
+	}
+	defer s.ownershipMu.Unlock()
+	return s.ownedProcessGroupsLocked()
+}
+
+func (s *Stack) ownedProcessGroupsLocked() []int {
+	var groups []int
+	for _, process := range []*supervisedProcess{s.AuthUI, s.Hydra, s.Kratos} {
+		if process != nil && process.pgid > 0 {
+			groups = append(groups, process.pgid)
+		}
+	}
+	return groups
+}
+
+func (s *Stack) stopOwnedProcess(process *supervisedProcess, timeout time.Duration) error {
+	if s.stopProcessOp != nil {
+		return s.stopProcessOp(process, timeout)
+	}
+	return process.stopAndWait(timeout)
+}
+
+func (s *Stack) stopProcessSet() error {
+	s.ownershipMu.Lock()
+	processes := []*supervisedProcess{s.AuthUI, s.Hydra, s.Kratos}
+	s.ownershipMu.Unlock()
+	var errs []string
+	for _, process := range processes {
+		if process == nil {
+			continue
+		}
+		stopErr := s.stopOwnedProcess(process, 5*time.Second)
+		if stopErr != nil {
+			errs = append(errs, stopErr.Error())
+		}
+		// Do not discard ownership merely because cleanup returned. Retain the
+		// process until its complete owned group is confirmed absent.
+		if ownedProcessGroupAlive(process.pgid) {
+			if stopErr == nil {
+				errs = append(errs, fmt.Sprintf("%s process group %d survived cleanup", process.name, process.pgid))
+			}
+		} else {
+			s.ownershipMu.Lock()
+			if s.AuthUI == process {
+				s.AuthUI = nil
+			}
+			if s.Hydra == process {
+				s.Hydra = nil
+			}
+			if s.Kratos == process {
+				s.Kratos = nil
+			}
+			s.ownershipMu.Unlock()
+		}
+	}
+	if len(errs) > 0 {
+		return fmt.Errorf("stop service processes: %s", strings.Join(errs, "; "))
+	}
+	return nil
+}
+
+func (s *Stack) StopServices() error {
+	if s == nil {
+		return nil
+	}
+	s.ownershipMu.Lock()
+	s.cleanupStarted = true
+	s.ownershipMu.Unlock()
+	s.stopOnce.Do(func() { s.stopErr = s.stopProcessSet() })
+	return s.stopErr
+}
+
+func (s *Stack) Close(success bool) error {
+	if s == nil {
+		return nil
+	}
+	stopErr := s.StopServices()
+	finalizeErr := s.Finalize(success)
+	if stopErr != nil && finalizeErr != nil {
+		return fmt.Errorf("%v; %w", stopErr, finalizeErr)
+	}
+	if stopErr != nil {
+		return stopErr
+	}
+	return finalizeErr
+}
+
+func (s *Stack) Finalize(success bool) error {
+	s.metadataMu.Lock()
+	ready, lastStatus := s.ready, s.lastStatus
+	redactions := append([]string(nil), s.redactions...)
+	s.metadataMu.Unlock()
+	if ready {
+		if success {
+			s.recordRun("passed", nil)
+		} else if lastStatus == "ready" {
+			s.recordRun("failed", nil)
+		}
+	}
+	var errs []string
+	services := filepath.Join(s.ArtifactDir, "services")
+	if err := os.MkdirAll(services, 0o700); err != nil {
+		errs = append(errs, err.Error())
+	}
+	for _, name := range []string{"auth-ui", "hydra", "kratos"} {
+		if err := copyFileBounded(s.logPath(name), filepath.Join(services, name+".log"), 1<<20, redactions); err != nil && !errors.Is(err, os.ErrNotExist) {
+			errs = append(errs, err.Error())
+		}
+	}
+	keep := !success || os.Getenv("AUTH_UI_E2E_KEEP_TMP") == "1"
+	if keep {
+		fmt.Fprintf(os.Stderr, "E2E workspace retained at %s\nE2E artifacts retained at %s\n", s.Workspace, s.ArtifactDir)
+	} else if err := os.RemoveAll(s.Workspace); err != nil {
+		errs = append(errs, err.Error())
+	}
+	if len(errs) > 0 {
+		return fmt.Errorf("stack cleanup: %s", strings.Join(errs, "; "))
+	}
+	return nil
+}
+
+func createRunArtifactDir(repo string) (string, error) {
+	root := os.Getenv("AUTH_UI_E2E_ARTIFACT_DIR")
+	if root == "" {
+		root = filepath.Join(repo, "e2e", "artifacts")
+	}
+	if err := os.MkdirAll(root, 0o700); err != nil {
+		return "", err
+	}
+	random, err := randomSecret(4)
+	if err != nil {
+		return "", err
+	}
+	name := fmt.Sprintf("%s-%d-%s", time.Now().UTC().Format("20060102T150405.000000000Z"), os.Getpid(), random)
+	path := filepath.Join(root, name)
+	return path, os.Mkdir(path, 0o700)
+}
+
+func (s *Stack) recordRun(status string, setupErr error) {
+	s.metadataMu.Lock()
+	defer s.metadataMu.Unlock()
+	if s.lastStatus == "watchdog_timeout" && status != "watchdog_timeout" {
+		return
+	}
+	s.lastStatus = status
+	metadata := map[string]any{"started_at": s.startedAt, "updated_at": time.Now().UTC(), "status": status, "workspace": s.Workspace, "platform": runtime.GOOS + "/" + runtime.GOARCH, "kratos_version": kratosVersion, "hydra_version": hydraVersion, "playwright_binding_version": playwrightVersion, "playwright_cli_version": playwrightCLIVersion, "chromium_revision": chromiumRevision, "chromium_version": chromiumVersion, "ffmpeg_revision": ffmpegRevision, "ports": s.Ports}
+	if setupErr != nil {
+		metadata["error"] = redactDiagnostic(setupErr.Error())
+	}
+	data, err := json.MarshalIndent(metadata, "", "  ")
+	if err == nil {
+		_ = os.WriteFile(filepath.Join(s.ArtifactDir, "run.json"), append(data, '\n'), 0o600)
+	}
+}
+
+func redactDiagnostic(value string) string {
+	// Text logs intentionally omit generated secrets. Strip query strings from URLs
+	// as a final guard against opaque flow/challenge/token values.
+	words := strings.Fields(value)
+	for i, word := range words {
+		if strings.Contains(word, "http://") && strings.Contains(word, "?") {
+			words[i] = strings.SplitN(word, "?", 2)[0]
+		}
+	}
+	return strings.Join(words, " ")
+}
+
+func copyFileBounded(source, destination string, limit int64, redactions []string) error {
+	f, err := os.Open(source)
+	if err != nil {
+		return err
+	}
+	defer f.Close()
+	info, err := f.Stat()
+	if err != nil {
+		return err
+	}
+	if info.Size() > limit {
+		if _, err := f.Seek(info.Size()-limit, io.SeekStart); err != nil {
+			return err
+		}
+	}
+	data, err := io.ReadAll(io.LimitReader(f, limit))
+	if err != nil {
+		return err
+	}
+	text := string(data)
+	for _, secret := range redactions {
+		if secret != "" {
+			text = strings.ReplaceAll(text, secret, "[REDACTED]")
+		}
+	}
+	return os.WriteFile(destination, []byte(text), 0o600)
+}
+
+func (s *Stack) healthy(endpoint string) error {
+	client := &http.Client{Timeout: 2 * time.Second}
+	defer client.CloseIdleConnections()
+	resp, err := client.Get(endpoint)
+	if err != nil {
+		return err
+	}
+	defer resp.Body.Close()
+	if resp.StatusCode < 200 || resp.StatusCode >= 300 {
+		return fmt.Errorf("health status %s", resp.Status)
+	}
+	return nil
+}
diff --git a/core/auth/ui/e2e/suite_test.go b/core/auth/ui/e2e/suite_test.go
new file mode 100644
index 0000000..4a49252
--- /dev/null
+++ b/core/auth/ui/e2e/suite_test.go
@@ -0,0 +1,186 @@
+//go:build e2e
+
+package e2e
+
+import (
+	"fmt"
+	"os"
+	"testing"
+	"time"
+
+	playwright "github.com/mxschmitt/playwright-go"
+)
+
+const emergencyExitProbeEnv = "AUTH_UI_E2E_EMERGENCY_EXIT_PROBE"
+
+var (
+	testStack   *Stack
+	testBrowser *browserRuntime
+)
+
+func TestMain(m *testing.M) {
+	if os.Getenv(emergencyExitProbeEnv) == "1" {
+		enumerateDescendantProcessIDs = func(int) ([]int, error) { select {} }
+		runBoundedEmergencyExit(nil, "injected emergency-exit probe")
+	}
+	if os.Getenv("AUTH_UI_E2E_PROCESS_HELPER") == "1" {
+		os.Exit(runTaggedProcessHelper())
+	}
+	watchdogTimeout, err := suiteWatchdogTimeout()
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "E2E watchdog setup failed: %v\n", err)
+		os.Exit(1)
+	}
+	lifecycle := newSuiteLifecycle(nil, nil)
+	activeSuiteLifecycle = lifecycle
+	watchdog := startSuiteWatchdog(watchdogTimeout, func() {
+		_ = lifecycle.claimTimeout()
+		finishWatchdogTimeoutOrWait(lifecycle, watchdogTimeout)
+	})
+
+	stack, err := startStackOwned(lifecycle)
+	if err != nil {
+		workspace, artifacts := lifecycle.diagnosticPaths()
+		fmt.Fprintf(os.Stderr, "E2E setup failed: %v\nworkspace: %s\nartifacts: %s\n", err, workspace, artifacts)
+		finishSetupFailure(lifecycle, watchdog, watchdogTimeout)
+	}
+	testStack = stack
+	if os.Getenv(watchdogSetupStallEnv) == "1" {
+		if err := publishWatchdogProbeReady(); err != nil {
+			fmt.Fprintf(os.Stderr, "E2E setup-timeout probe failed: %v\n", err)
+			finishSetupFailure(lifecycle, watchdog, watchdogTimeout)
+		}
+		select {}
+	}
+
+	runtime, err := startBrowserRuntimeOwned(lifecycle)
+	if err != nil {
+		stack.recordRun("browser_setup_failed", err)
+		fmt.Fprintf(os.Stderr, "E2E browser setup failed: %v\nworkspace: %s\nartifacts: %s\n", err, stack.Workspace, stack.ArtifactDir)
+		finishSetupFailure(lifecycle, watchdog, watchdogTimeout)
+	}
+	testBrowser = runtime
+	if err := probeLoginPage(runtime.Browser, stack); err != nil {
+		stack.recordRun("ui_readiness_failed", err)
+		fmt.Fprintf(os.Stderr, "E2E UI readiness failed: %v\nworkspace: %s\nartifacts: %s\n", err, stack.Workspace, stack.ArtifactDir)
+		finishSetupFailure(lifecycle, watchdog, watchdogTimeout)
+	}
+
+	code := m.Run()
+	reason := lifecycle.claimAfterRun(watchdog)
+	if reason == terminalTimeout {
+		finishWatchdogTimeoutOrWait(lifecycle, watchdogTimeout)
+	}
+	if err := finishNormalWithEmergencyBound(lifecycle, code == 0); err != nil {
+		fmt.Fprintf(os.Stderr, "E2E suite cleanup failed: %s\n", redactDiagnostic(err.Error()))
+		code = 1
+	}
+	os.Exit(code)
+}
+
+func finishSetupFailure(lifecycle *suiteLifecycle, watchdog *suiteWatchdog, watchdogTimeout time.Duration) {
+	reason := lifecycle.claimAfterRun(watchdog)
+	if reason == terminalTimeout {
+		finishWatchdogTimeoutOrWait(lifecycle, watchdogTimeout)
+	}
+	if err := finishNormalWithEmergencyBound(lifecycle, false); err != nil {
+		fmt.Fprintf(os.Stderr, "E2E setup cleanup failed: %s\n", redactDiagnostic(err.Error()))
+	}
+	os.Exit(1)
+}
+
+func finishNormalWithEmergencyBound(lifecycle *suiteLifecycle, success bool) error {
+	cleanupExit := time.AfterFunc(watchdogCleanupExitTimeout, func() {
+		runBoundedEmergencyExit(lifecycle, "normal cleanup exceeded its 45s protocol bound")
+	})
+	err := lifecycle.finish(success)
+	stopCleanupTimerOrWait(cleanupExit.Stop, waitForEmergencyExit)
+	return err
+}
+
+func runBoundedEmergencyExit(lifecycle *suiteLifecycle, reason string) {
+	// Arm the unconditional guard before any process enumeration. Even a hung
+	// external ps invocation cannot postpone exit beyond this short grace.
+	unconditionalExit := time.AfterFunc(emergencyCleanupExitGrace, func() {
+		fmt.Fprintf(os.Stderr, "E2E emergency cleanup exceeded its %s grace; exiting unconditionally\n", emergencyCleanupExitGrace)
+		os.Exit(125)
+	})
+	var emergencyErr error
+	if lifecycle != nil {
+		emergencyErr = lifecycle.emergencyTerminate()
+	} else {
+		emergencyErr = emergencyTerminateOwnedProcesses(os.Getpid(), nil)
+	}
+	if emergencyErr != nil {
+		fmt.Fprintf(os.Stderr, "E2E emergency process cleanup failed: %s\n", redactDiagnostic(emergencyErr.Error()))
+	}
+	fmt.Fprintf(os.Stderr, "E2E %s\n", reason)
+	unconditionalExit.Stop()
+	os.Exit(125)
+}
+
+func finishWatchdogTimeoutOrWait(lifecycle *suiteLifecycle, timeout time.Duration) {
+	if lifecycle.claimTimeoutExit() {
+		runWatchdogTimeoutExit(lifecycle, timeout)
+	}
+	select {}
+}
+
+func runWatchdogTimeoutExit(lifecycle *suiteLifecycle, timeout time.Duration) {
+	workspace, artifacts := lifecycle.diagnosticPaths()
+	fmt.Fprintf(os.Stderr, "E2E internal watchdog reached %s; finalizing owned sessions and processes before the Go test timeout\nworkspace: %s\nartifacts: %s\n", timeout, workspace, artifacts)
+	cleanupExit := time.AfterFunc(watchdogCleanupExitTimeout, func() {
+		runBoundedEmergencyExit(lifecycle, "watchdog cleanup exceeded its 45s protocol bound")
+	})
+	if err := lifecycle.finish(false); err != nil {
+		fmt.Fprintf(os.Stderr, "E2E watchdog cleanup failed: %s\n", redactDiagnostic(err.Error()))
+	}
+	// Reap any owned descendant that appeared after the protocol cleanup
+	// snapshots (for example FFmpeg or a late driver child) before normal
+	// watchdog exit as well as on the emergency path.
+	if err := lifecycle.emergencyTerminate(); err != nil {
+		fmt.Fprintf(os.Stderr, "E2E final descendant cleanup failed: %s\n", redactDiagnostic(err.Error()))
+	}
+	stopCleanupTimerOrWait(cleanupExit.Stop, waitForEmergencyExit)
+	os.Exit(124)
+}
+
+func probeLoginPage(browser playwright.Browser, stack *Stack) error {
+	context, err := browser.NewContext(playwright.BrowserNewContextOptions{Viewport: &playwright.Size{Width: 1280, Height: 720}, ServiceWorkers: playwright.ServiceWorkerPolicyBlock})
+	if err != nil {
+		return err
+	}
+	defer context.Close()
+	policy := newRoutePolicy(stack.allowedOrigins())
+	if err := context.Route("**/*", func(route playwright.Route) {
+		if policy(route.Request().URL()) {
+			_ = route.Continue()
+		} else {
+			_ = route.Abort("blockedbyclient")
+		}
+	}); err != nil {
+		return err
+	}
+	page, err := context.NewPage()
+	if err != nil {
+		return err
+	}
+	page.SetDefaultTimeout(15_000)
+	if _, err := page.Goto(stack.UIURL + "/login"); err != nil {
+		return err
+	}
+	for _, selector := range []string{`input[name="username"]`, `input[name="password"]`} {
+		visible, err := page.Locator(selector).IsVisible()
+		if err != nil {
+			return err
+		}
+		if !visible {
+			return fmt.Errorf("login selector %s is not visible at %s", selector, sanitizeFinalURL(page.URL()))
+		}
+	}
+	return nil
+}
+
+func (s *Stack) allowedOrigins() []string {
+	return []string{s.UIURL, s.APIURL, s.KratosURL, s.KratosAdmin, s.HydraURL, s.HydraAdmin}
+}
diff --git a/core/auth/ui/e2e/testdata/hydra.yml.tmpl b/core/auth/ui/e2e/testdata/hydra.yml.tmpl
new file mode 100644
index 0000000..047c1c2
--- /dev/null
+++ b/core/auth/ui/e2e/testdata/hydra.yml.tmpl
@@ -0,0 +1,36 @@
+dsn: memory
+
+serve:
+  cookies:
+    same_site_mode: Lax
+  public:
+    host: 127.0.0.1
+    port: {{.HydraPublicPort}}
+  admin:
+    host: 127.0.0.1
+    port: {{.HydraAdminPort}}
+
+urls:
+  self:
+    issuer: {{.HydraPublicURL}}/
+  login: {{.UIURL}}/login
+  consent: {{.UIURL}}/consent
+  logout: {{.UIURL}}/logout
+  error: {{.UIURL}}/error
+
+secrets:
+  system:
+    - {{.HydraSecret}}
+
+log:
+  level: info
+  format: text
+  leak_sensitive_values: false
+
+oidc:
+  subject_identifiers:
+    supported_types:
+      - public
+      - pairwise
+    pairwise:
+      salt: {{.HydraSecret}}
diff --git a/core/auth/ui/e2e/testdata/identity.schema.json b/core/auth/ui/e2e/testdata/identity.schema.json
new file mode 100644
index 0000000..f37a3df
--- /dev/null
+++ b/core/auth/ui/e2e/testdata/identity.schema.json
@@ -0,0 +1,27 @@
+{
+  "$id": "https://schemas.ory.sh/presets/kratos/quickstart/email-password/identity.schema.json",
+  "$schema": "http://json-schema.org/draft-07/schema#",
+  "title": "User",
+  "type": "object",
+  "properties": {
+    "traits": {
+      "type": "object",
+      "properties": {
+        "username": {
+          "type": "string",
+          "format": "username",
+          "title": "Username",
+          "minLength": 3,
+          "ory.sh/kratos": {
+            "credentials": {
+              "password": {
+                "identifier": true
+              }
+            }
+          }
+        }
+      },
+      "additionalProperties": false
+    }
+  }
+}
diff --git a/core/auth/ui/e2e/testdata/kratos.yml.tmpl b/core/auth/ui/e2e/testdata/kratos.yml.tmpl
new file mode 100644
index 0000000..820786a
--- /dev/null
+++ b/core/auth/ui/e2e/testdata/kratos.yml.tmpl
@@ -0,0 +1,74 @@
+version: v1.1.0
+dsn: memory
+
+serve:
+  public:
+    base_url: {{.KratosPublicURL}}/
+    host: 127.0.0.1
+    port: {{.KratosPublicPort}}
+    cors:
+      enabled: false
+  admin:
+    base_url: {{.KratosAdminURL}}/
+    host: 127.0.0.1
+    port: {{.KratosAdminPort}}
+
+selfservice:
+  default_browser_return_url: {{.UIURL}}/
+  allowed_return_urls:
+    - {{.UIURL}}/
+  methods:
+    password:
+      enabled: true
+  flows:
+    error:
+      ui_url: {{.UIURL}}/error
+    settings:
+      ui_url: {{.UIURL}}/settings
+    recovery:
+      enabled: false
+      ui_url: {{.UIURL}}/recovery
+    verification:
+      enabled: false
+      ui_url: {{.UIURL}}/verification
+    logout:
+      after:
+        default_browser_return_url: {{.UIURL}}/login
+    login:
+      ui_url: {{.UIURL}}/login
+    registration:
+      enabled: true
+      ui_url: {{.UIURL}}/register
+      after:
+        password:
+          hooks:
+            - hook: session
+
+log:
+  level: info
+  format: text
+  leak_sensitive_values: false
+
+secrets:
+  cookie:
+    - {{.CookieSecret}}
+  cipher:
+    - {{.CipherSecret}}
+
+ciphers:
+  algorithm: xchacha20-poly1305
+
+hashers:
+  algorithm: bcrypt
+  bcrypt:
+    cost: 4
+
+identity:
+  default_schema_id: user
+  schemas:
+    - id: user
+      url: {{.SchemaURL}}
+
+courier:
+  smtp:
+    connection_uri: smtp://e2e:e2e@127.0.0.1:{{.SMTPPort}}/?skip_ssl_verify=true
diff --git a/core/auth/ui/e2e/watchdog.go b/core/auth/ui/e2e/watchdog.go
new file mode 100644
index 0000000..5705c63
--- /dev/null
+++ b/core/auth/ui/e2e/watchdog.go
@@ -0,0 +1,379 @@
+package e2e
+
+import (
+	"fmt"
+	"os"
+	"sort"
+	"strings"
+	"sync"
+	"time"
+)
+
+const (
+	// The harness deadline includes setup and leaves one minute before Make's
+	// exact 10-minute Go timeout for cleanup and the emergency exit bound.
+	defaultSuiteWatchdogTimeout = 9 * time.Minute
+	watchdogCleanupExitTimeout  = 45 * time.Second
+	emergencyCleanupExitGrace   = 5 * time.Second
+	suiteWatchdogTimeoutEnv     = "AUTH_UI_E2E_WATCHDOG_TIMEOUT"
+)
+
+type sessionClaim uint8
+
+const (
+	sessionUnclaimed sessionClaim = iota
+	sessionNormal
+	sessionTimeout
+)
+
+type sessionEntry struct {
+	claim sessionClaim
+	done  chan struct{}
+	err   error
+}
+
+type sessionRegistry struct {
+	mu       sync.Mutex
+	sessions map[*browserSession]*sessionEntry
+	timedOut bool
+}
+
+func newSessionRegistry() *sessionRegistry {
+	return &sessionRegistry{sessions: make(map[*browserSession]*sessionEntry)}
+}
+
+func (r *sessionRegistry) add(session *browserSession) bool {
+	if r == nil || session == nil {
+		return false
+	}
+	r.mu.Lock()
+	defer r.mu.Unlock()
+	if r.timedOut {
+		return false
+	}
+	r.sessions[session] = &sessionEntry{done: make(chan struct{})}
+	return true
+}
+
+func (r *sessionRegistry) finalizeNormal(session *browserSession) error {
+	if r == nil {
+		return session.finalizeClaimed(false)
+	}
+	r.mu.Lock()
+	entry := r.sessions[session]
+	if entry == nil {
+		r.mu.Unlock()
+		return session.finalizeClaimed(false)
+	}
+	owner := entry.claim == sessionUnclaimed
+	if owner {
+		entry.claim = sessionNormal
+	}
+	r.mu.Unlock()
+	if owner {
+		err := session.finalizeClaimed(false)
+		r.complete(session, entry, err)
+		return err
+	}
+	<-entry.done
+	return entry.err
+}
+
+func (r *sessionRegistry) complete(session *browserSession, entry *sessionEntry, err error) {
+	r.mu.Lock()
+	entry.err = err
+	delete(r.sessions, session)
+	close(entry.done)
+	r.mu.Unlock()
+}
+
+func (r *sessionRegistry) finalizeAfterTimeout() error {
+	if r == nil {
+		return nil
+	}
+	r.mu.Lock()
+	r.timedOut = true
+	type claimedSession struct {
+		session *browserSession
+		entry   *sessionEntry
+		owner   bool
+	}
+	claimed := make([]claimedSession, 0, len(r.sessions))
+	for session, entry := range r.sessions {
+		owner := entry.claim == sessionUnclaimed
+		if owner {
+			entry.claim = sessionTimeout
+		}
+		claimed = append(claimed, claimedSession{session: session, entry: entry, owner: owner})
+	}
+	r.mu.Unlock()
+	sort.Slice(claimed, func(i, j int) bool { return claimed[i].session.dir < claimed[j].session.dir })
+	var errs []string
+	for _, claim := range claimed {
+		if claim.owner {
+			err := claim.session.finalizeClaimed(true)
+			r.complete(claim.session, claim.entry, err)
+		}
+		<-claim.entry.done
+		if claim.entry.err != nil {
+			errs = append(errs, fmt.Sprintf("%s: %v", filepathBase(claim.session.dir), claim.entry.err))
+		}
+	}
+	if len(errs) > 0 {
+		return fmt.Errorf("finalize timed-out browser sessions: %s", strings.Join(errs, "; "))
+	}
+	return nil
+}
+
+// filepathBase avoids putting full retained paths into aggregate errors.
+func filepathBase(path string) string {
+	for len(path) > 1 && os.IsPathSeparator(path[len(path)-1]) {
+		path = path[:len(path)-1]
+	}
+	if i := strings.LastIndexAny(path, `/\\`); i >= 0 {
+		return path[i+1:]
+	}
+	return path
+}
+
+type ownedCloser interface{ Close() error }
+
+type closerRegistry struct {
+	mu      sync.Mutex
+	closers map[ownedCloser]struct{}
+	closing bool
+}
+
+func newCloserRegistry() *closerRegistry {
+	return &closerRegistry{closers: make(map[ownedCloser]struct{})}
+}
+
+func (r *closerRegistry) add(closer ownedCloser) bool {
+	if r == nil || closer == nil {
+		return false
+	}
+	r.mu.Lock()
+	defer r.mu.Unlock()
+	if r.closing {
+		return false
+	}
+	r.closers[closer] = struct{}{}
+	return true
+}
+
+func (r *closerRegistry) remove(closer ownedCloser) {
+	if r == nil || closer == nil {
+		return
+	}
+	r.mu.Lock()
+	delete(r.closers, closer)
+	r.mu.Unlock()
+}
+
+func (r *closerRegistry) closeAll() error {
+	if r == nil {
+		return nil
+	}
+	r.mu.Lock()
+	r.closing = true
+	closers := make([]ownedCloser, 0, len(r.closers))
+	for closer := range r.closers {
+		closers = append(closers, closer)
+		delete(r.closers, closer)
+	}
+	r.mu.Unlock()
+	var errs []string
+	for _, closer := range closers {
+		if err := closer.Close(); err != nil {
+			errs = append(errs, err.Error())
+		}
+	}
+	if len(errs) > 0 {
+		return fmt.Errorf("close owned listeners: %s", strings.Join(errs, "; "))
+	}
+	return nil
+}
+
+type terminalReason uint8
+
+const (
+	terminalRunning terminalReason = iota
+	terminalNormal
+	terminalTimeout
+)
+
+type suiteLifecycle struct {
+	mu                 sync.Mutex
+	reason             terminalReason
+	timeoutExitClaimed bool
+	stack              *Stack
+	browser            *browserRuntime
+	sessions           *sessionRegistry
+	closers            *closerRegistry
+
+	finishOnce sync.Once
+	finishErr  error
+}
+
+// Installed before tagged-suite setup and retained until process exit.
+var activeSuiteLifecycle *suiteLifecycle
+
+func newSuiteLifecycle(stack *Stack, browser *browserRuntime) *suiteLifecycle {
+	return &suiteLifecycle{stack: stack, browser: browser, sessions: newSessionRegistry(), closers: newCloserRegistry()}
+}
+
+func (l *suiteLifecycle) setStack(stack *Stack) bool {
+	l.mu.Lock()
+	defer l.mu.Unlock()
+	if l.reason != terminalRunning {
+		return false
+	}
+	l.stack = stack
+	return true
+}
+
+func (l *suiteLifecycle) setBrowser(browser *browserRuntime) bool {
+	l.mu.Lock()
+	defer l.mu.Unlock()
+	if l.reason != terminalRunning {
+		return false
+	}
+	l.browser = browser
+	return true
+}
+
+func (l *suiteLifecycle) claimTimeout() bool {
+	l.mu.Lock()
+	defer l.mu.Unlock()
+	if l.reason != terminalRunning {
+		return false
+	}
+	l.reason = terminalTimeout
+	return true
+}
+
+// claimAfterRun stops and claims normal cleanup atomically. If the timer is
+// already firing, this caller claims timeout completion so timeout status and
+// artifacts cannot be lost while the callback is waiting to run.
+func (l *suiteLifecycle) claimAfterRun(watchdog *suiteWatchdog) terminalReason {
+	l.mu.Lock()
+	defer l.mu.Unlock()
+	if l.reason != terminalRunning {
+		return l.reason
+	}
+	if watchdog != nil && !watchdog.timer.Stop() {
+		l.reason = terminalTimeout
+	} else {
+		l.reason = terminalNormal
+	}
+	return l.reason
+}
+
+func (l *suiteLifecycle) claimTimeoutExit() bool {
+	l.mu.Lock()
+	defer l.mu.Unlock()
+	if l.reason != terminalTimeout || l.timeoutExitClaimed {
+		return false
+	}
+	l.timeoutExitClaimed = true
+	return true
+}
+
+func (l *suiteLifecycle) currentReason() terminalReason {
+	l.mu.Lock()
+	defer l.mu.Unlock()
+	return l.reason
+}
+
+func (l *suiteLifecycle) diagnosticPaths() (workspace, artifacts string) {
+	l.mu.Lock()
+	stack := l.stack
+	l.mu.Unlock()
+	if stack != nil {
+		return stack.Workspace, stack.ArtifactDir
+	}
+	return "unavailable (setup incomplete)", "unavailable (setup incomplete)"
+}
+
+func (l *suiteLifecycle) finish(success bool) error {
+	if l == nil {
+		return nil
+	}
+	l.finishOnce.Do(func() {
+		l.mu.Lock()
+		reason, stack, browser := l.reason, l.stack, l.browser
+		l.mu.Unlock()
+		timedOut := reason == terminalTimeout
+		var errs []string
+		if timedOut && stack != nil {
+			stack.recordRun("watchdog_timeout", fmt.Errorf("internal E2E suite deadline exceeded"))
+		}
+		if timedOut {
+			if err := l.sessions.finalizeAfterTimeout(); err != nil {
+				errs = append(errs, err.Error())
+			}
+		}
+		if err := l.closers.closeAll(); err != nil {
+			errs = append(errs, err.Error())
+		}
+		if stack != nil {
+			if err := stack.StopServices(); err != nil {
+				errs = append(errs, "services: "+err.Error())
+			}
+		}
+		if browser != nil {
+			if err := browser.Close(); err != nil {
+				errs = append(errs, "browser: "+err.Error())
+			}
+		}
+		finalSuccess := success && !timedOut && len(errs) == 0
+		if stack != nil {
+			if err := stack.Finalize(finalSuccess); err != nil {
+				errs = append(errs, "artifacts: "+err.Error())
+			}
+		}
+		if len(errs) > 0 {
+			l.finishErr = fmt.Errorf("E2E suite cleanup: %s", strings.Join(errs, "; "))
+		}
+	})
+	return l.finishErr
+}
+
+func (l *suiteLifecycle) emergencyTerminate() error {
+	l.mu.Lock()
+	stack := l.stack
+	l.mu.Unlock()
+	var groups []int
+	if stack != nil {
+		groups = stack.emergencyProcessGroups()
+	}
+	return emergencyTerminateOwnedProcesses(os.Getpid(), groups)
+}
+
+func suiteWatchdogTimeout() (time.Duration, error) {
+	value := os.Getenv(suiteWatchdogTimeoutEnv)
+	if value == "" {
+		return defaultSuiteWatchdogTimeout, nil
+	}
+	duration, err := time.ParseDuration(value)
+	if err != nil || duration <= 0 {
+		return 0, fmt.Errorf("%s must be a positive Go duration", suiteWatchdogTimeoutEnv)
+	}
+	return duration, nil
+}
+
+type suiteWatchdog struct{ timer *time.Timer }
+
+func startSuiteWatchdog(timeout time.Duration, fire func()) *suiteWatchdog {
+	return &suiteWatchdog{timer: time.AfterFunc(timeout, fire)}
+}
+
+func (w *suiteWatchdog) stop() bool { return w == nil || w.timer.Stop() }
+
+func stopCleanupTimerOrWait(stop func() bool, wait func()) {
+	if !stop() {
+		wait()
+	}
+}
+
+func waitForEmergencyExit() { select {} }
diff --git a/core/auth/ui/e2e/watchdog_subprocess_test.go b/core/auth/ui/e2e/watchdog_subprocess_test.go
new file mode 100644
index 0000000..b7dc51e
--- /dev/null
+++ b/core/auth/ui/e2e/watchdog_subprocess_test.go
@@ -0,0 +1,600 @@
+//go:build e2e
+
+package e2e
+
+import (
+	"archive/zip"
+	"bytes"
+	"encoding/json"
+	"fmt"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"strconv"
+	"strings"
+	"sync"
+	"testing"
+	"time"
+)
+
+const (
+	watchdogProbeChildEnv = "AUTH_UI_E2E_WATCHDOG_PROBE_CHILD"
+	watchdogProbeReadyEnv = "AUTH_UI_E2E_WATCHDOG_PROBE_READY_FILE"
+	watchdogSetupStallEnv = "AUTH_UI_E2E_WATCHDOG_SETUP_STALL"
+)
+
+type processIdentity struct {
+	PID     int    `json:"pid"`
+	Command string `json:"command"`
+}
+
+type watchdogProbeState struct {
+	Workspace   string            `json:"workspace"`
+	ArtifactDir string            `json:"artifact_dir"`
+	Processes   []processIdentity `json:"processes"`
+}
+
+func TestWatchdogTimeoutCleanup(t *testing.T) {
+	if os.Getenv(watchdogProbeChildEnv) == "1" {
+		runWatchdogProbeChild(t)
+		return
+	}
+
+	// The tagged parent regression is a normal real-browser test and therefore
+	// retains the same complete artifact set as every other tagged test.
+	parentSession := newWatchdogProbeSession(t)
+	if _, err := parentSession.Page.Goto(testStack.UIURL + "/login"); err != nil {
+		t.Fatal(err)
+	}
+	if err := parentSession.Checkpoint("watchdog-regression-parent"); err != nil {
+		t.Fatal(err)
+	}
+
+	childRoot := t.TempDir()
+	readyFile := filepath.Join(childRoot, "ready.json")
+	executable, err := os.Executable()
+	if err != nil {
+		t.Fatal(err)
+	}
+	cmd := exec.Command(executable, "-test.run=^TestWatchdogTimeoutCleanup$", "-test.count=1", "-test.timeout=2m", "-test.v")
+	cmd.Env = environmentWithOverrides(map[string]string{
+		watchdogProbeChildEnv:      "1",
+		watchdogProbeReadyEnv:      readyFile,
+		suiteWatchdogTimeoutEnv:    "20s",
+		"AUTH_UI_E2E_OFFLINE":      "1",
+		"AUTH_UI_E2E_ARTIFACT_DIR": filepath.Join(childRoot, "artifacts"),
+	})
+	if err := configureOwnedProcess(cmd); err != nil {
+		t.Fatal(err)
+	}
+	var output bytes.Buffer
+	cmd.Stdout = &output
+	cmd.Stderr = &output
+	if err := cmd.Start(); err != nil {
+		t.Fatal(err)
+	}
+
+	var state watchdogProbeState
+	var observedMu sync.Mutex
+	observed := make(map[int]processIdentity)
+	monitorStop := make(chan struct{})
+	monitorDone := make(chan struct{})
+	var monitorStopOnce sync.Once
+	stopMonitor := func() {
+		monitorStopOnce.Do(func() {
+			close(monitorStop)
+			<-monitorDone
+		})
+	}
+	go func() {
+		defer close(monitorDone)
+		ticker := time.NewTicker(50 * time.Millisecond)
+		defer ticker.Stop()
+		for {
+			if identities, snapshotErr := descendantProcessIdentities(cmd.Process.Pid); snapshotErr == nil {
+				observedMu.Lock()
+				for _, identity := range identities {
+					observed[identity.PID] = identity
+				}
+				observedMu.Unlock()
+			}
+			select {
+			case <-monitorStop:
+				return
+			case <-ticker.C:
+			}
+		}
+	}()
+	cleanupChild := func() {
+		stopMonitor()
+		if cmd.Process != nil && cmd.ProcessState == nil {
+			if identities, snapshotErr := descendantProcessIdentities(cmd.Process.Pid); snapshotErr == nil {
+				observedMu.Lock()
+				for _, identity := range identities {
+					observed[identity.PID] = identity
+				}
+				observedMu.Unlock()
+			}
+			_ = signalOwnedProcessGroup(cmd.Process.Pid, processKill)
+		}
+		observedMu.Lock()
+		allObserved := make([]processIdentity, 0, len(observed)+len(state.Processes))
+		for _, process := range observed {
+			allObserved = append(allObserved, process)
+		}
+		observedMu.Unlock()
+		allObserved = append(allObserved, state.Processes...)
+		for _, process := range allObserved {
+			if ownedProcessStillMatches(process) {
+				if p, findErr := os.FindProcess(process.PID); findErr == nil {
+					_ = p.Kill()
+				}
+			}
+		}
+		if state.Workspace != "" {
+			_ = os.RemoveAll(state.Workspace)
+		}
+	}
+	t.Cleanup(cleanupChild)
+
+	waitDone := make(chan error, 1)
+	go func() { waitDone <- cmd.Wait() }()
+	var waitErr error
+	select {
+	case waitErr = <-waitDone:
+	case <-time.After(90 * time.Second):
+		if readyData, readErr := os.ReadFile(readyFile); readErr == nil {
+			_ = json.Unmarshal(readyData, &state)
+		}
+		cleanupChild()
+		select {
+		case waitErr = <-waitDone:
+		case <-time.After(5 * time.Second):
+			t.Fatal("watchdog subprocess did not exit after forced cleanup")
+		}
+		t.Fatalf("watchdog subprocess exceeded its 90s outer regression deadline: %v", waitErr)
+	}
+
+	stopMonitor()
+	readyData, err := os.ReadFile(readyFile)
+	if err != nil || json.Unmarshal(readyData, &state) != nil {
+		t.Fatalf("watchdog child did not publish ownership state: %v\noutput:\n%s", err, boundedText(output.Bytes(), 16<<10))
+	}
+	observedMu.Lock()
+	for _, process := range observed {
+		state.Processes = appendUniqueProcessIdentity(state.Processes, process)
+	}
+	observedMu.Unlock()
+	if exitErr, ok := waitErr.(*exec.ExitError); !ok || exitErr.ExitCode() != 124 {
+		t.Fatalf("watchdog child exit=%v, want status 124\noutput:\n%s", waitErr, boundedText(output.Bytes(), 16<<10))
+	}
+	if !strings.Contains(output.String(), "E2E internal watchdog reached 20s") {
+		t.Fatalf("watchdog child omitted timeout diagnostic:\n%s", boundedText(output.Bytes(), 16<<10))
+	}
+
+	assertWatchdogChildArtifacts(t, state)
+	assertWatchdogOwnedProcessesGone(t, state.Processes)
+	if ownedProcessGroupAlive(cmd.Process.Pid) {
+		t.Fatalf("watchdog child process group %d survived", cmd.Process.Pid)
+	}
+	childSession := filepath.Join(state.ArtifactDir, sanitizeName("TestWatchdogTimeoutCleanup"))
+	video, _ := os.Stat(filepath.Join(childSession, "video.webm"))
+	trace, _ := os.Stat(filepath.Join(childSession, "trace.zip"))
+	finalPNG, _ := os.Stat(filepath.Join(childSession, "screenshots", "99-final.png"))
+	failurePNG, _ := os.Stat(filepath.Join(childSession, "screenshots", "failure.png"))
+	t.Logf("watchdog child verified: exit=124 status=watchdog_timeout owned_processes=%d video=%d trace=%d final_png=%d failure_png=%d", len(state.Processes), video.Size(), trace.Size(), finalPNG.Size(), failurePNG.Size())
+}
+
+func TestEmergencyExitBoundsBlockedDescendantEnumerator(t *testing.T) {
+	parentSession := newWatchdogProbeSession(t)
+	if _, err := parentSession.Page.Goto(testStack.UIURL + "/login"); err != nil {
+		t.Fatal(err)
+	}
+	if err := parentSession.Checkpoint("emergency-exit-regression-parent"); err != nil {
+		t.Fatal(err)
+	}
+
+	executable, err := os.Executable()
+	if err != nil {
+		t.Fatal(err)
+	}
+	cmd := exec.Command(executable, "-test.run=^TestEmergencyExitBoundsBlockedDescendantEnumerator$", "-test.count=1", "-test.timeout=30s", "-test.v")
+	cmd.Env = environmentWithOverrides(map[string]string{emergencyExitProbeEnv: "1"})
+	if err := configureOwnedProcess(cmd); err != nil {
+		t.Fatal(err)
+	}
+	var output bytes.Buffer
+	cmd.Stdout, cmd.Stderr = &output, &output
+	started := time.Now()
+	if err := cmd.Start(); err != nil {
+		t.Fatal(err)
+	}
+	t.Cleanup(func() {
+		if cmd.ProcessState == nil {
+			_ = signalOwnedProcessGroup(cmd.Process.Pid, processKill)
+		}
+	})
+	waitDone := make(chan error, 1)
+	go func() { waitDone <- cmd.Wait() }()
+	var waitErr error
+	select {
+	case waitErr = <-waitDone:
+	case <-time.After(10 * time.Second):
+		t.Fatal("emergency-exit probe exceeded its outer 10s bound")
+	}
+	elapsed := time.Since(started)
+	if exitErr, ok := waitErr.(*exec.ExitError); !ok || exitErr.ExitCode() != 125 {
+		t.Fatalf("emergency-exit probe=%v, want status 125\n%s", waitErr, boundedText(output.Bytes(), 8192))
+	}
+	if elapsed > 8*time.Second || !strings.Contains(output.String(), "emergency cleanup exceeded its 5s grace") {
+		t.Fatalf("emergency-exit elapsed=%s output=%s", elapsed, boundedText(output.Bytes(), 8192))
+	}
+	if strings.Contains(output.String(), "E2E setup failed") || strings.Contains(output.String(), "workspace:") {
+		t.Fatalf("emergency helper unexpectedly entered suite setup: %s", boundedText(output.Bytes(), 8192))
+	}
+	t.Logf("blocked-enumerator emergency exit verified: status=125 elapsed=%s", elapsed.Round(time.Millisecond))
+}
+
+func TestWatchdogCoversSetupTimeout(t *testing.T) {
+	parentSession := newWatchdogProbeSession(t)
+	if _, err := parentSession.Page.Goto(testStack.UIURL + "/login"); err != nil {
+		t.Fatal(err)
+	}
+	if err := parentSession.Checkpoint("setup-watchdog-regression-parent"); err != nil {
+		t.Fatal(err)
+	}
+
+	childRoot := t.TempDir()
+	readyFile := filepath.Join(childRoot, "setup-ready.json")
+	executable, err := os.Executable()
+	if err != nil {
+		t.Fatal(err)
+	}
+	cmd := exec.Command(executable, "-test.run=^TestWatchdogCoversSetupTimeout$", "-test.count=1", "-test.timeout=2m", "-test.v")
+	cmd.Env = environmentWithOverrides(map[string]string{
+		watchdogSetupStallEnv:      "1",
+		watchdogProbeReadyEnv:      readyFile,
+		suiteWatchdogTimeoutEnv:    "20s",
+		"AUTH_UI_E2E_OFFLINE":      "1",
+		"AUTH_UI_E2E_ARTIFACT_DIR": filepath.Join(childRoot, "artifacts"),
+	})
+	if err := configureOwnedProcess(cmd); err != nil {
+		t.Fatal(err)
+	}
+	var output bytes.Buffer
+	cmd.Stdout, cmd.Stderr = &output, &output
+	if err := cmd.Start(); err != nil {
+		t.Fatal(err)
+	}
+	var state watchdogProbeState
+	t.Cleanup(func() {
+		if cmd.ProcessState == nil {
+			if fallback, snapshotErr := descendantProcessIdentities(cmd.Process.Pid); snapshotErr == nil {
+				state.Processes = append(state.Processes, fallback...)
+			}
+			_ = signalOwnedProcessGroup(cmd.Process.Pid, processKill)
+		}
+		for _, process := range state.Processes {
+			if ownedProcessStillMatches(process) {
+				if owned, findErr := os.FindProcess(process.PID); findErr == nil {
+					_ = owned.Kill()
+				}
+			}
+		}
+		if state.Workspace != "" {
+			_ = os.RemoveAll(state.Workspace)
+		}
+	})
+	waitDone := make(chan error, 1)
+	go func() { waitDone <- cmd.Wait() }()
+	var waitErr error
+	select {
+	case waitErr = <-waitDone:
+	case <-time.After(90 * time.Second):
+		t.Fatal("setup watchdog subprocess exceeded 90s")
+	}
+	readyData, err := os.ReadFile(readyFile)
+	if err != nil || json.Unmarshal(readyData, &state) != nil {
+		t.Fatalf("setup watchdog child omitted ownership state: %v\n%s", err, boundedText(output.Bytes(), 16<<10))
+	}
+	if exitErr, ok := waitErr.(*exec.ExitError); !ok || exitErr.ExitCode() != 124 {
+		t.Fatalf("setup watchdog child exit=%v, want 124\n%s", waitErr, boundedText(output.Bytes(), 16<<10))
+	}
+	if !strings.Contains(output.String(), "E2E internal watchdog reached 20s") {
+		t.Fatalf("setup watchdog diagnostic missing:\n%s", boundedText(output.Bytes(), 16<<10))
+	}
+	runData, err := os.ReadFile(filepath.Join(state.ArtifactDir, "run.json"))
+	var run map[string]any
+	if err != nil || json.Unmarshal(runData, &run) != nil || run["status"] != "watchdog_timeout" || run["workspace"] != state.Workspace {
+		t.Fatalf("setup watchdog run metadata invalid: %v %s", err, runData)
+	}
+	for _, service := range []string{"auth-ui", "hydra", "kratos"} {
+		if _, statErr := os.Stat(filepath.Join(state.ArtifactDir, "services", service+".log")); statErr != nil {
+			t.Errorf("setup watchdog omitted retained %s log: %v", service, statErr)
+		}
+	}
+	assertWatchdogSetupProcessesGone(t, state.Processes)
+	if ownedProcessGroupAlive(cmd.Process.Pid) {
+		t.Fatalf("setup watchdog child group %d survived", cmd.Process.Pid)
+	}
+	t.Logf("setup watchdog child verified: exit=124 status=watchdog_timeout owned_processes=%d", len(state.Processes))
+}
+
+func newWatchdogProbeSession(t *testing.T) *browserSession {
+	t.Helper()
+	dir := filepath.Join(testStack.ArtifactDir, sanitizeName(t.Name()))
+	failedBeforeFinalize := false
+	t.Cleanup(func() { assertArtifactSet(t, dir, failedBeforeFinalize) })
+	session, err := newBrowserSession(t, testBrowser.Browser, testStack.ArtifactDir, testStack.allowedOrigins())
+	if err != nil {
+		t.Fatal(err)
+	}
+	t.Cleanup(func() { failedBeforeFinalize = t.Failed() })
+	return session
+}
+
+func runWatchdogProbeChild(t *testing.T) {
+	session := newWatchdogProbeSession(t)
+	if _, err := session.Page.Goto(testStack.UIURL + "/login"); err != nil {
+		t.Fatal(err)
+	}
+	if err := session.Checkpoint("stalled-real-session"); err != nil {
+		t.Fatal(err)
+	}
+	if err := publishWatchdogProbeReady(); err != nil {
+		t.Fatal(err)
+	}
+	// Spawn an independently grouped descendant after ready.json so the parent
+	// proves its continuous fallback accounting and the harness's final
+	// non-protocol descendant sweep, not merely the original snapshot.
+	late := exec.Command(os.Args[0], "-test.run=^TestProcessHelper$")
+	late.Env = environmentWithOverrides(map[string]string{
+		"AUTH_UI_E2E_PROCESS_HELPER": "1",
+		"AUTH_UI_E2E_PROCESS_MODE":   "ignore-term",
+	})
+	if err := configureOwnedProcess(late); err != nil {
+		t.Fatal(err)
+	}
+	if err := late.Start(); err != nil {
+		t.Fatal(err)
+	}
+	go func() { _ = late.Wait() }()
+	// The initial publication above still predates the independently grouped
+	// spawn. Republish only after bounded polling observes the exact late PID,
+	// making the final ownership proof deterministic while retaining the
+	// parent's continuous monitor and kill-time fallback.
+	if err := publishWatchdogProbeReadyAfterProcess(late.Process.Pid); err != nil {
+		t.Fatal(err)
+	}
+	select {}
+}
+
+func publishWatchdogProbeReady() error {
+	return publishWatchdogProbeReadyAfterProcess(0)
+}
+
+func publishWatchdogProbeReadyAfterProcess(requiredPID int) error {
+	deadline := time.NewTimer(2 * time.Second)
+	defer deadline.Stop()
+	poll := time.NewTicker(10 * time.Millisecond)
+	defer poll.Stop()
+	for {
+		processes, err := descendantProcessIdentities(os.Getpid())
+		if err != nil {
+			return err
+		}
+		observed := requiredPID == 0
+		for _, process := range processes {
+			if process.PID == requiredPID && strings.Contains(strings.ToLower(process.Command), "testprocesshelper") {
+				observed = true
+				break
+			}
+		}
+		if observed {
+			return writeWatchdogProbeReady(processes)
+		}
+		select {
+		case <-deadline.C:
+			return fmt.Errorf("late watchdog helper process %d was not observable before readiness deadline", requiredPID)
+		case <-poll.C:
+		}
+	}
+}
+
+func writeWatchdogProbeReady(processes []processIdentity) error {
+	if testStack == nil {
+		return fmt.Errorf("watchdog probe stack ownership is unavailable")
+	}
+	state := watchdogProbeState{Workspace: testStack.Workspace, ArtifactDir: testStack.ArtifactDir, Processes: processes}
+	data, err := json.MarshalIndent(state, "", "  ")
+	if err != nil {
+		return err
+	}
+	readyFile := os.Getenv(watchdogProbeReadyEnv)
+	if readyFile == "" {
+		return fmt.Errorf("watchdog probe ready path is missing")
+	}
+	temporary, err := os.CreateTemp(filepath.Dir(readyFile), ".watchdog-ready-*")
+	if err != nil {
+		return err
+	}
+	temporaryPath := temporary.Name()
+	defer os.Remove(temporaryPath)
+	if err := temporary.Chmod(0o600); err != nil {
+		_ = temporary.Close()
+		return err
+	}
+	if _, err := temporary.Write(append(data, '\n')); err != nil {
+		_ = temporary.Close()
+		return err
+	}
+	if err := temporary.Close(); err != nil {
+		return err
+	}
+	return os.Rename(temporaryPath, readyFile)
+}
+
+func appendUniqueProcessIdentity(processes []processIdentity, candidate processIdentity) []processIdentity {
+	for _, process := range processes {
+		if process.PID == candidate.PID {
+			return processes
+		}
+	}
+	return append(processes, candidate)
+}
+
+func environmentWithOverrides(overrides map[string]string) []string {
+	environment := make([]string, 0, len(os.Environ())+len(overrides))
+	for _, entry := range os.Environ() {
+		name := strings.SplitN(entry, "=", 2)[0]
+		if _, overridden := overrides[name]; !overridden {
+			environment = append(environment, entry)
+		}
+	}
+	for name, value := range overrides {
+		environment = append(environment, name+"="+value)
+	}
+	return environment
+}
+
+func descendantProcessIdentities(rootPID int) ([]processIdentity, error) {
+	output, err := exec.Command("ps", "-eo", "pid=,ppid=,command=").Output()
+	if err != nil {
+		return nil, fmt.Errorf("list watchdog-owned processes: %w", err)
+	}
+	type entry struct {
+		pid, ppid int
+		command   string
+	}
+	var entries []entry
+	for _, line := range strings.Split(string(output), "\n") {
+		fields := strings.Fields(line)
+		if len(fields) < 3 {
+			continue
+		}
+		pid, pidErr := strconv.Atoi(fields[0])
+		ppid, ppidErr := strconv.Atoi(fields[1])
+		if pidErr == nil && ppidErr == nil {
+			entries = append(entries, entry{pid: pid, ppid: ppid, command: strings.Join(fields[2:], " ")})
+		}
+	}
+	owned := map[int]bool{rootPID: true}
+	for changed := true; changed; {
+		changed = false
+		for _, entry := range entries {
+			if owned[entry.ppid] && !owned[entry.pid] {
+				owned[entry.pid] = true
+				changed = true
+			}
+		}
+	}
+	var result []processIdentity
+	for _, entry := range entries {
+		if entry.pid != rootPID && owned[entry.pid] {
+			result = append(result, processIdentity{PID: entry.pid, Command: entry.command})
+		}
+	}
+	return result, nil
+}
+
+func ownedProcessStillMatches(want processIdentity) bool {
+	output, err := exec.Command("ps", "-p", strconv.Itoa(want.PID), "-o", "command=").Output()
+	return err == nil && strings.TrimSpace(string(output)) == want.Command
+}
+
+func assertWatchdogSetupProcessesGone(t *testing.T, processes []processIdentity) {
+	t.Helper()
+	services := map[string]bool{"kratos": false, "hydra": false, "auth-ui": false}
+	for _, process := range processes {
+		command := strings.ToLower(process.Command)
+		for service := range services {
+			if strings.Contains(command, "/bin/"+service) {
+				services[service] = true
+			}
+		}
+		if ownedProcessStillMatches(process) {
+			t.Errorf("setup-watchdog process survived: pid=%d command=%s", process.PID, boundedText([]byte(process.Command), 512))
+		}
+	}
+	for service, found := range services {
+		if !found {
+			t.Errorf("setup watchdog ownership snapshot did not include %s", service)
+		}
+	}
+}
+
+func assertWatchdogOwnedProcessesGone(t *testing.T, processes []processIdentity) {
+	t.Helper()
+	categories := map[string]bool{"kratos": false, "hydra": false, "auth-ui": false, "driver": false, "chromium": false, "late-helper": false}
+	for _, process := range processes {
+		command := strings.ToLower(process.Command)
+		for _, service := range []string{"kratos", "hydra", "auth-ui"} {
+			if strings.Contains(command, "/bin/"+service) {
+				categories[service] = true
+			}
+		}
+		if strings.Contains(command, "playwright.sh run-driver") || strings.Contains(command, "cli.js run-driver") {
+			categories["driver"] = true
+		}
+		if strings.Contains(command, "chrome") || strings.Contains(command, "chromium") {
+			categories["chromium"] = true
+		}
+		if strings.Contains(command, "testprocesshelper") {
+			categories["late-helper"] = true
+		}
+		if ownedProcessStillMatches(process) {
+			t.Errorf("watchdog-owned process survived: pid=%d command=%s", process.PID, boundedText([]byte(process.Command), 512))
+		}
+	}
+	for category, found := range categories {
+		if !found {
+			t.Errorf("watchdog ownership snapshot did not include %s", category)
+		}
+	}
+}
+
+func assertWatchdogChildArtifacts(t *testing.T, state watchdogProbeState) {
+	t.Helper()
+	if state.Workspace == "" || state.ArtifactDir == "" {
+		t.Fatalf("incomplete watchdog state: %+v", state)
+	}
+	runData, err := os.ReadFile(filepath.Join(state.ArtifactDir, "run.json"))
+	if err != nil {
+		t.Fatal(err)
+	}
+	var run map[string]any
+	if err := json.Unmarshal(runData, &run); err != nil || run["status"] != "watchdog_timeout" || run["workspace"] != state.Workspace {
+		t.Fatalf("invalid watchdog run metadata: error=%v data=%s", err, runData)
+	}
+	for _, service := range []string{"auth-ui", "hydra", "kratos"} {
+		info, statErr := os.Stat(filepath.Join(state.ArtifactDir, "services", service+".log"))
+		if statErr != nil {
+			t.Errorf("retained %s service log missing: info=%v error=%v", service, info, statErr)
+		} else if service != "auth-ui" && info.Size() == 0 {
+			t.Errorf("retained %s service log is empty", service)
+		}
+	}
+	sessionDir := filepath.Join(state.ArtifactDir, sanitizeName("TestWatchdogTimeoutCleanup"))
+	for _, path := range []string{"screenshots/99-final.png", "screenshots/failure.png", "video.webm", "trace.zip", "session.json"} {
+		info, statErr := os.Stat(filepath.Join(sessionDir, path))
+		if statErr != nil || info.Size() == 0 {
+			t.Fatalf("watchdog artifact %s missing or empty: info=%v error=%v", path, info, statErr)
+		}
+	}
+	for _, name := range []string{"99-final.png", "failure.png"} {
+		png, readErr := os.ReadFile(filepath.Join(sessionDir, "screenshots", name))
+		if readErr != nil || !bytes.HasPrefix(png, []byte("\x89PNG\r\n\x1a\n")) {
+			t.Fatalf("watchdog %s is not a PNG: %v", name, readErr)
+		}
+	}
+	trace, err := zip.OpenReader(filepath.Join(sessionDir, "trace.zip"))
+	if err != nil || len(trace.File) == 0 {
+		t.Fatalf("watchdog trace is not a valid non-empty ZIP: %v", err)
+	}
+	_ = trace.Close()
+	sessionData, err := os.ReadFile(filepath.Join(sessionDir, "session.json"))
+	var metadata sessionMetadata
+	if err != nil || json.Unmarshal(sessionData, &metadata) != nil || metadata.Outcome != "failed" || !containsString(metadata.Screenshots, "failure.png") {
+		t.Fatalf("invalid watchdog session metadata: error=%v data=%s", err, sessionData)
+	}
+}
diff --git a/core/auth/ui/e2e/watchdog_test.go b/core/auth/ui/e2e/watchdog_test.go
new file mode 100644
index 0000000..5a2500c
--- /dev/null
+++ b/core/auth/ui/e2e/watchdog_test.go
@@ -0,0 +1,206 @@
+package e2e
+
+import (
+	"encoding/json"
+	"os"
+	"path/filepath"
+	"sync/atomic"
+	"testing"
+	"time"
+)
+
+func TestSuiteWatchdogTimeoutConfiguration(t *testing.T) {
+	t.Setenv(suiteWatchdogTimeoutEnv, "")
+	if got, err := suiteWatchdogTimeout(); err != nil || got != 9*time.Minute {
+		t.Fatalf("default timeout=%s error=%v", got, err)
+	}
+	t.Setenv(suiteWatchdogTimeoutEnv, "250ms")
+	if got, err := suiteWatchdogTimeout(); err != nil || got != 250*time.Millisecond {
+		t.Fatalf("override timeout=%s error=%v", got, err)
+	}
+	for _, value := range []string{"0", "-1s", "not-a-duration"} {
+		t.Setenv(suiteWatchdogTimeoutEnv, value)
+		if _, err := suiteWatchdogTimeout(); err == nil {
+			t.Fatalf("invalid timeout %q was accepted", value)
+		}
+	}
+}
+
+func TestStopCleanupTimerOrWaitHonorsTimerWinner(t *testing.T) {
+	waits := 0
+	stopCleanupTimerOrWait(func() bool { return true }, func() { waits++ })
+	if waits != 0 {
+		t.Fatalf("wait called after timer was stopped: %d", waits)
+	}
+	stopCleanupTimerOrWait(func() bool { return false }, func() { waits++ })
+	if waits != 1 {
+		t.Fatalf("already-fired timer did not own exit wait: %d", waits)
+	}
+}
+
+func TestNormalTerminalClaimStopsWatchdogBeforeCleanup(t *testing.T) {
+	lifecycle := newSuiteLifecycle(nil, nil)
+	fired := make(chan struct{}, 1)
+	watchdog := startSuiteWatchdog(time.Hour, func() {
+		if lifecycle.claimTimeout() {
+			fired <- struct{}{}
+		}
+	})
+	if got := lifecycle.claimAfterRun(watchdog); got != terminalNormal {
+		t.Fatalf("terminal reason=%v, want normal", got)
+	}
+	if err := lifecycle.finish(true); err != nil {
+		t.Fatal(err)
+	}
+	select {
+	case <-fired:
+		t.Fatal("stopped watchdog claimed cleanup")
+	case <-time.After(20 * time.Millisecond):
+	}
+}
+
+func TestTimeoutTerminalClaimCannotBeLostToNormalCleanup(t *testing.T) {
+	lifecycle := newSuiteLifecycle(nil, nil)
+	if !lifecycle.claimTimeout() {
+		t.Fatal("timeout did not claim terminal state")
+	}
+	watchdog := startSuiteWatchdog(time.Hour, func() {})
+	defer watchdog.stop()
+	if got := lifecycle.claimAfterRun(watchdog); got != terminalTimeout {
+		t.Fatalf("terminal reason=%v, want timeout", got)
+	}
+	if err := lifecycle.finish(false); err != nil {
+		t.Fatal(err)
+	}
+	if lifecycle.sessions.add(&browserSession{}) {
+		t.Fatal("timeout cleanup did not close session registry")
+	}
+}
+
+func newRegistryTestSession(t *testing.T, name string) (*browserSession, *sessionRegistry, *atomic.Int32) {
+	t.Helper()
+	dir := filepath.Join(t.TempDir(), name)
+	if err := os.MkdirAll(filepath.Join(dir, "screenshots"), 0o700); err != nil {
+		t.Fatal(err)
+	}
+	registry := newSessionRegistry()
+	reporter := &fakeReporter{name: name}
+	session := &browserSession{t: reporter, dir: dir, started: time.Unix(1, 0).UTC(), browserVer: chromiumVersion, registry: registry}
+	var screenshots atomic.Int32
+	session.screenshotOp = func(path string) error {
+		screenshots.Add(1)
+		return os.WriteFile(path, []byte("png"), 0o600)
+	}
+	session.stopTraceOp = func(path string) error { return os.WriteFile(path, []byte("trace"), 0o600) }
+	session.closeContextOp = func() error { return nil }
+	session.saveVideoOp = func(path string) error { return os.WriteFile(path, []byte("video"), 0o600) }
+	session.finalURLOp = func() string { return "http://127.0.0.1:1234/login?flow=secret" }
+	if !registry.add(session) {
+		t.Fatal("registry rejected session")
+	}
+	return session, registry, &screenshots
+}
+
+func TestSessionNormalClaimWinsAndTimeoutAwaitsIt(t *testing.T) {
+	session, registry, screenshots := newRegistryTestSession(t, "TestNormalWinner")
+	started, release := make(chan struct{}), make(chan struct{})
+	originalScreenshot := session.screenshotOp
+	session.screenshotOp = func(path string) error {
+		if screenshots.Load() == 0 {
+			close(started)
+			<-release
+		}
+		return originalScreenshot(path)
+	}
+	normalDone := make(chan error, 1)
+	go func() { normalDone <- session.Finalize() }()
+	<-started
+	timeoutDone := make(chan error, 1)
+	go func() { timeoutDone <- registry.finalizeAfterTimeout() }()
+	select {
+	case <-timeoutDone:
+		t.Fatal("timeout did not await normally claimed finalization")
+	case <-time.After(20 * time.Millisecond):
+	}
+	close(release)
+	if err := <-normalDone; err != nil {
+		t.Fatal(err)
+	}
+	if err := <-timeoutDone; err != nil {
+		t.Fatal(err)
+	}
+	assertRegistryMetadata(t, session.dir, "passed", false)
+	if screenshots.Load() != 1 {
+		t.Fatalf("normal winner screenshots=%d, want one final capture", screenshots.Load())
+	}
+}
+
+func TestSessionTimeoutClaimWinsAndNormalAwaitsFailedFinalization(t *testing.T) {
+	session, registry, screenshots := newRegistryTestSession(t, "TestTimeoutWinner")
+	started, release := make(chan struct{}), make(chan struct{})
+	originalScreenshot := session.screenshotOp
+	session.screenshotOp = func(path string) error {
+		if screenshots.Load() == 0 {
+			close(started)
+			<-release
+		}
+		return originalScreenshot(path)
+	}
+	timeoutDone := make(chan error, 1)
+	go func() { timeoutDone <- registry.finalizeAfterTimeout() }()
+	<-started
+	normalDone := make(chan error, 1)
+	go func() { normalDone <- session.Finalize() }()
+	select {
+	case <-normalDone:
+		t.Fatal("normal finalization did not await timeout claim")
+	case <-time.After(20 * time.Millisecond):
+	}
+	close(release)
+	if err := <-timeoutDone; err != nil {
+		t.Fatal(err)
+	}
+	if err := <-normalDone; err != nil {
+		t.Fatal(err)
+	}
+	assertRegistryMetadata(t, session.dir, "failed", true)
+	if screenshots.Load() != 2 {
+		t.Fatalf("timeout winner screenshots=%d, want final and failure", screenshots.Load())
+	}
+}
+
+func assertRegistryMetadata(t *testing.T, dir, outcome string, failurePNG bool) {
+	t.Helper()
+	data, err := os.ReadFile(filepath.Join(dir, "session.json"))
+	var metadata sessionMetadata
+	if err != nil || json.Unmarshal(data, &metadata) != nil {
+		t.Fatalf("session metadata: %v %s", err, data)
+	}
+	if metadata.Outcome != outcome || containsString(metadata.Screenshots, "failure.png") != failurePNG {
+		t.Fatalf("metadata=%+v", metadata)
+	}
+}
+
+type countedCloser struct{ calls atomic.Int32 }
+
+func (c *countedCloser) Close() error { c.calls.Add(1); return nil }
+
+func TestCloserRegistryClosesExactlyOnceAndRejectsLateOwnership(t *testing.T) {
+	closer := &countedCloser{}
+	registry := newCloserRegistry()
+	if !registry.add(closer) {
+		t.Fatal("closer registry rejected ownership")
+	}
+	if err := registry.closeAll(); err != nil {
+		t.Fatal(err)
+	}
+	if err := registry.closeAll(); err != nil {
+		t.Fatal(err)
+	}
+	if closer.calls.Load() != 1 {
+		t.Fatalf("closer calls=%d", closer.calls.Load())
+	}
+	if registry.add(&countedCloser{}) {
+		t.Fatal("closer registry accepted ownership after cleanup")
+	}
+}
diff --git a/core/auth/ui/go.mod b/core/auth/ui/go.mod
index 0930937..cf0dd37 100644
--- a/core/auth/ui/go.mod
+++ b/core/auth/ui/go.mod
@@ -1,16 +1,21 @@
 module github.com/giolekva/pcloud/core/auth/ui
 
-go 1.20
+go 1.22
 
 require (
 	github.com/gorilla/mux v1.8.0
 	github.com/itaysk/regogo v0.0.0-20200423164851-e9433c1fe5a7
+	github.com/mxschmitt/playwright-go v0.6100.0
 )
 
 require (
 	github.com/OneOfOne/xxhash v1.2.7 // indirect
+	github.com/deckarep/golang-set/v2 v2.8.0 // indirect
 	github.com/ghodss/yaml v0.0.0-20180820084758-c7ce16629ff4 // indirect
+	github.com/go-jose/go-jose/v3 v3.0.5 // indirect
+	github.com/go-stack/stack v1.8.1 // indirect
 	github.com/gobwas/glob v0.2.3 // indirect
+	github.com/kr/text v0.2.0 // indirect
 	github.com/open-policy-agent/opa v0.18.0 // indirect
 	github.com/pkg/errors v0.0.0-20181023235946-059132a15dd0 // indirect
 	github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a // indirect
diff --git a/core/auth/ui/go.sum b/core/auth/ui/go.sum
index 69c993e..b548d65 100644
--- a/core/auth/ui/go.sum
+++ b/core/auth/ui/go.sum
@@ -5,14 +5,24 @@
 github.com/OneOfOne/xxhash v1.2.7/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
 github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
 github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
+github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/deckarep/golang-set/v2 v2.8.0 h1:swm0rlPCmdWn9mESxKOjWk8hXSqoxOp+ZlfuyaAdFlQ=
+github.com/deckarep/golang-set/v2 v2.8.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4=
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
 github.com/ghodss/yaml v0.0.0-20180820084758-c7ce16629ff4 h1:bRzFpEzvausOAt4va+I/22BZ1vXDtERngp0BNYDKej0=
 github.com/ghodss/yaml v0.0.0-20180820084758-c7ce16629ff4/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
+github.com/go-jose/go-jose/v3 v3.0.5 h1:BLLJWbC4nMZOfuPVxoZIxeYsn6Nl2r1fITaJ78UQlVQ=
+github.com/go-jose/go-jose/v3 v3.0.5/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
+github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw=
+github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4=
 github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
 github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
 github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
 github.com/golang/protobuf v0.0.0-20181025225059-d3de96c4c28e/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
+github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/gorilla/mux v0.0.0-20181024020800-521ea7b17d02/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
 github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
 github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
@@ -23,15 +33,22 @@
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
 github.com/mattn/go-runewidth v0.0.0-20181025052659-b20a3daf6a39/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
 github.com/mna/pigeon v0.0.0-20180808201053-bb0192cfc2ae/go.mod h1:Iym28+kJVnC1hfQvv5MUtI6AiFFzvQjHcvI4RFTG/04=
+github.com/mxschmitt/playwright-go v0.6100.0 h1:HYNnbGZsTHz8veJyDGe4fU1iPxfvXqzmwKchzuvGCsY=
+github.com/mxschmitt/playwright-go v0.6100.0/go.mod h1:A7VtrS3j/c8ToGnSVUaOfNtQQVxi6JotUS0jeuus6r4=
 github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
 github.com/open-policy-agent/opa v0.18.0 h1:EC81mO3/517Kq5brJHydqKE5MLzJ+4cdJvUQKxLzHy8=
 github.com/open-policy-agent/opa v0.18.0/go.mod h1:6pC1cMYDI92i9EY/GoA2m+HcZlcCrh3jbfny5F7JVTA=
 github.com/peterh/liner v0.0.0-20170211195444-bf27d3ba8e1d/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
 github.com/pkg/errors v0.0.0-20181023235946-059132a15dd0 h1:R+lX9nKwNd1n7UE5SQAyoorREvRn3aLF6ZndXBoIWqY=
 github.com/pkg/errors v0.0.0-20181023235946-059132a15dd0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/prometheus/client_golang v0.0.0-20181025174421-f30f42803563/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
 github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
@@ -39,35 +56,80 @@
 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
 github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ=
 github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
+github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
+github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
 github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
 github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
 github.com/spf13/cobra v0.0.0-20181021141114-fe5e611709b0/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
 github.com/spf13/pflag v0.0.0-20181024212040-082b515c9490/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
-github.com/tidwall/gjson v1.6.0 h1:9VEQWz6LLMUsUl6PueE49ir4Ka6CzLymOAZDxpFsTDc=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
+github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
 github.com/tidwall/gjson v1.6.0/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls=
-github.com/tidwall/match v1.0.1 h1:PnKP62LPNxHKTwvHHZZzdOAOCtsJTjo6dZLCwpKm5xc=
+github.com/tidwall/gjson v1.17.0 h1:/Jocvlh98kcTfpN2+JzGQWQcqrPQwDrVEMApx/M5ZwM=
+github.com/tidwall/gjson v1.17.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
 github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E=
-github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
+github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
+github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
 github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
+github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
+github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
 github.com/yashtewari/glob-intersection v0.0.0-20180916065949-5c77d914dd0b h1:vVRagRXf67ESqAb72hG2C/ZwI8NtJF2u2V76EsuOHGY=
 github.com/yashtewari/glob-intersection v0.0.0-20180916065949-5c77d914dd0b/go.mod h1:HptNXiXVDcJjXe9SqMd0v2FsL9f8dz4GnXgltU6q/co=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
 golang.org/x/lint v0.0.0-20181023182221-1baf3a9d7d67/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
+golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
 gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
 gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/core/auth/ui/main.go b/core/auth/ui/main.go
index 73561e7..978ddc7 100644
--- a/core/auth/ui/main.go
+++ b/core/auth/ui/main.go
@@ -134,8 +134,8 @@
 	s.r.Path("/consent").Methods(http.MethodGet).HandlerFunc(s.consent)
 	s.r.Path("/consent").Methods(http.MethodPost).HandlerFunc(s.processConsent)
 	s.r.Path("/logout").Methods(http.MethodGet).HandlerFunc(s.logout)
-	s.r.Path("/change-password").Methods("POST").HandlerFunc(s.changePassword)
-	s.r.Path("/change-password").Methods("GET").HandlerFunc(s.changePasswordForm)
+	s.r.Path("/settings").Methods("POST").HandlerFunc(s.changePassword)
+	s.r.Path("/settings").Methods("GET").HandlerFunc(s.changePasswordForm)
 	s.r.Path("/").HandlerFunc(s.whoami)
 	return s.serv.ListenAndServe()
 }
@@ -593,20 +593,28 @@
 type changePasswordData struct {
 	Username       string
 	Password       string
+	CSRFToken      string
+	FormAction     string
 	PasswordErrors []ValidationError
 }
 
 func (s *Server) changePasswordForm(w http.ResponseWriter, r *http.Request) {
-	_, username, err := getWhoAmIFromKratos(r.Cookies())
-	if err != nil {
-		if errors.Is(err, ErrNotLoggedIn) {
-			http.Redirect(w, r, "/", http.StatusSeeOther)
-		} else {
-			http.Error(w, err.Error(), http.StatusInternalServerError)
-		}
+	flow := r.FormValue("flow")
+	if flow == "" {
+		http.Redirect(w, r, s.kratos+"/self-service/settings/browser", http.StatusSeeOther)
 		return
 	}
-	if err := s.tmpls.ChangePassword.Execute(w, changePasswordData{Username: username}); err != nil {
+	_, username, err := getWhoAmIFromKratos(r.Cookies())
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+	csrfToken, err := getCSRFToken("settings", flow, r.Cookies())
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+	if err := s.tmpls.ChangePassword.Execute(w, changePasswordData{Username: username, CSRFToken: csrfToken, FormAction: r.URL.Path + "?flow=" + url.QueryEscape(flow)}); err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
@@ -617,28 +625,46 @@
 		http.Error(w, err.Error(), http.StatusBadRequest)
 		return
 	}
+	flow := r.FormValue("flow")
+	if flow == "" {
+		http.Redirect(w, r, s.kratos+"/self-service/settings/browser", http.StatusSeeOther)
+		return
+	}
 	password := r.FormValue("password")
-	id, username, err := getWhoAmIFromKratos(r.Cookies())
+	_, username, err := getWhoAmIFromKratos(r.Cookies())
 	if err != nil {
-		if errors.Is(err, ErrNotLoggedIn) {
-			http.Redirect(w, r, "/", http.StatusSeeOther)
-		} else {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+	if verr := validatePassword(password); len(verr) > 0 {
+		if err := s.tmpls.ChangePassword.Execute(w, changePasswordData{Username: username, Password: password, CSRFToken: r.FormValue("csrf_token"), FormAction: r.URL.Path + "?flow=" + url.QueryEscape(flow), PasswordErrors: verr}); err != nil {
 			http.Error(w, err.Error(), http.StatusInternalServerError)
 		}
 		return
 	}
-	if verr, err := s.api.apiPasswordChange(id, username, password); err != nil {
+	resp, err := postFormToKratos("settings", flow, r.Cookies(), url.Values{
+		"csrf_token": {r.FormValue("csrf_token")},
+		"method":     {"password"},
+		"password":   {password},
+	})
+	if err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
-	} else if len(verr) > 0 {
-		if err := s.tmpls.ChangePassword.Execute(w, changePasswordData{username, password, verr}); err != nil {
-			http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+	defer resp.Body.Close()
+	if resp.StatusCode >= http.StatusBadRequest {
+		if err := extractError(resp.Body); err != nil {
+			if renderErr := s.tmpls.ChangePassword.Execute(w, changePasswordData{Username: username, Password: password, CSRFToken: r.FormValue("csrf_token"), FormAction: r.URL.Path + "?flow=" + url.QueryEscape(flow), PasswordErrors: []ValidationError{{Field: "password", Message: err.Error()}}}); renderErr != nil {
+				http.Error(w, renderErr.Error(), http.StatusInternalServerError)
+			}
 			return
 		}
-	} else {
-		if err := s.tmpls.ChangePasswordSuccess.Execute(w, nil); err != nil {
-			http.Error(w, err.Error(), http.StatusInternalServerError)
-			return
-		}
+		http.Error(w, "password change failed", resp.StatusCode)
+		return
+	}
+	if err := s.tmpls.ChangePasswordSuccess.Execute(w, nil); err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
 	}
 }
 
diff --git a/core/auth/ui/templates/change-password.html b/core/auth/ui/templates/change-password.html
index 4d0b487..ca5ea0b 100644
--- a/core/auth/ui/templates/change-password.html
+++ b/core/auth/ui/templates/change-password.html
@@ -4,7 +4,7 @@
 	<div class="logo">
 		<span>do</span><span>do:</span>
 	</div>
-	<form action="" method="POST">
+	<form action="{{ .FormAction }}" method="POST">
 		<label>
 			new password
 			<input type="password" name="password" aria-label="Password" value="{{ .Password }}" aria-invalid="{{ if .PasswordErrors }}true{{ else }}undefined{{ end }}" required/>
@@ -17,6 +17,8 @@
 		{{ end }}
 		{{ end }}
 		<button type="submit">change password</button>
+		<input type="hidden" name="csrf_token" value="{{ .CSRFToken }}" />
+		<input type="hidden" name="method" value="password" />
 		<input type="hidden" name="username" value="{{ .Username }}" />
 	</form>
 </div>
diff --git a/core/auth/ui/templates/whoami.html b/core/auth/ui/templates/whoami.html
index 944ed28..01be060 100644
--- a/core/auth/ui/templates/whoami.html
+++ b/core/auth/ui/templates/whoami.html
@@ -1,5 +1,6 @@
 {{ define "title" }}dodo: who am i{{ end }}
 {{ define "main" }}
 Hello {{.}}!
+<a href="/settings" role="button">change password</a>
 <a href="/logout" role="button">logout</a>
 {{ end }}
