El journey empieza en el plano de identidad, dueño InsForge. Tres altas
(magic link 15 min / OAuth / password), todas crean/autentican un user de InsForge
(lib/server/auth.ts, routes/api/auth/*). Sesión en cookie insforge_session httpOnly
(hooks.server.ts:24-31), access token ~15 min refrescado server-side. Fail-closed: error →
null. Frontera: al nacer, la cuenta solo existe en InsForge; el substrato no se entera.
Nudo: crear cuenta ≠ tener acceso ≠ crear squad.
Crear una cuenta de prueba real (email que controles) por magic link en
https://app.agentsquadai.com. *(No hay signup-con-password en el código —solo sessions login,
refresh, oauth/exchange—; por eso el alta va por magic link, que sí existe: magicLink.ts.)*
read -rp "email de prueba: " EMAIL; read -rsp "password: " PW; echo
# TP-A1 · autenticar por el MISMO endpoint que auth.ts:30 → user.id DINÁMICO
RESP=$(curl -s -X POST "$IBASE/api/auth/sessions?client_type=server" \
-H "content-type: application/json" -H "apikey: $IANON" \
-d "{\"email\":\"$EMAIL\",\"password\":\"$PW\"}")
UID=$(echo "$RESP" | jq -r '.user.id // empty')
[ -n "$UID" ] && echo "TP-A1 OK · sesión válida · user.id=$UID" || { echo "TP-A1 FAIL (fail-closed)"; }
# TP-A2 · el gate del user recién nacido — query EXACTA de access.ts:38 con el UID descubierto
curl -s -H "Authorization: Bearer $ISK" \
"$IBASE/api/database/records/user_access?user_id=eq.$UID&select=authorized" | jq -c \
| sed 's/^/TP-A2 · user_access = /' # [] → no autorizado (fail-closed) → gateado a /welcome
línea TP-A1 (user.id=…) + línea TP-A2 ([]).