k6 performance gate

Run against the local mesh:

k6 run -e K6_MODE=users -e BASE_URL=http://127.0.0.1:8010 \
  -e ADMIN_EMAIL=admin@example.local \
  -e ADMIN_PASSWORD='local-root-access-2026!' scripts/k6/performance.js

K6_MODE=users ramps the directory to 100 virtual users. K6_MODE=login runs a bounded login storm (configure LOGIN_RATE/LOGIN_DURATION), while K6_MODE=soak holds 25 VUs for one hour by default (SOAK_VUS and SOAK_DURATION are overrideable). Every profile fails above 1% errors, 250 ms p95, or 500 ms p99. The reproducible pre-change machine baseline is recorded in docs/SCALING.md (9,249 rps for the gateway health path and 225 ms login p95 at bcrypt cost 10). k6 results are deliberately machine and deployment specific; paste the summary below for each release candidate rather than comparing numbers from unlike hardware.

Date Revision Environment p95 p99 Error rate
2026-08-28 performance baseline local Windows/Docker mesh gate ≤250 ms gate ≤500 ms gate <1%