KeiSeiKit-1.0/skills/auth-setup/phase-1-intake.md
Parfii-bot 0be354a920 KeiSeiKit-public — clean state
Single-commit clean baseline after security scrub of niche-tells,
project codenames, internal jargon, and contributor-email leaks.

Contents:
- 100 Rust crates (_primitives/_rust/)
- 37 agent manifests (_manifests/) + generated specs (_generated/)
- 67 user-invocable skills (skills/)
- 33 hooks (hooks/)
- Composition blocks (_blocks/)
- Documentation (docs/, README.md)
- TS adapter packages (_ts_packages/)
- Assembler (_assembler/)
- Roles (_roles/)
- Templates (_templates/)
- Forgejo CI (.forgejo/)

Author: Denis Parfionovich <info@greendragon.info>

License: see LICENSE.
2026-05-01 12:09:03 +08:00

4.3 KiB

Phase 1 — Intake (flows, stack, storage, MFA)

One free-text paragraph, then four click batches. This is the only phase that accepts typed input.

1a — Ask for the app description

Emit a regular message (NOT AskUserQuestion):

Describe the app in one paragraph: what is it, who signs in, and any constraint I should know (regulated industry, existing user table, multi-tenant, mobile-first, etc.). Reply in one message.

Store the reply verbatim as INTAKE.

1b — User-flow click (AskUserQuestion, multi-select)

{
  "questions": [
    {
      "question": "Which login flows should the app support?",
      "header": "Flows",
      "multiSelect": true,
      "options": [
        {"label": "Email + password",   "description": "Classic — requires password hash (argon2id), breach-check (HIBP), reset email flow"},
        {"label": "Magic link",         "description": "Email-only, one-time link; removes password surface, depends on email deliverability"},
        {"label": "OAuth / social",     "description": "Google / GitHub / Apple / Microsoft — see _blocks/auth-oauth2-oidc.md"},
        {"label": "Passkey (WebAuthn)", "description": "Phishing-resistant, passwordless — see _blocks/auth-passkeys.md"},
        {"label": "Enterprise SSO",     "description": "SAML / OIDC to Okta / Entra ID / Keycloak — B2B multi-tenant"}
      ]
    }
  ]
}

Store the multi-selection as FLOWS. Empty selection → re-ask.

1c — Stack click (AskUserQuestion, single-select)

{
  "questions": [
    {
      "question": "Primary framework / runtime?",
      "header": "Stack",
      "multiSelect": false,
      "options": [
        {"label": "Next.js (App Router)", "description": "Server Components + Server Actions; Better-Auth or Auth.js"},
        {"label": "Remix / React Router", "description": "Loader/action model; remix-auth + Better-Auth"},
        {"label": "SvelteKit",            "description": "Hooks + form actions; Lucia replacement = Better-Auth or custom"},
        {"label": "Astro",                "description": "Islands + middleware; Better-Auth or external auth"},
        {"label": "Rust (axum / actix)",  "description": "axum-login + tower-sessions + webauthn-rs + openidconnect-rs"},
        {"label": "Python (FastAPI)",     "description": "authlib + starlette SessionMiddleware + py_webauthn"},
        {"label": "Other / specify",      "description": "Add a free-text note; skill will pick libraries in Phase 2"}
      ]
    }
  ]
}

Store as STACK.

1d — Storage click (AskUserQuestion, single-select)

{
  "questions": [
    {
      "question": "Where will user + session rows live?",
      "header": "Storage",
      "multiSelect": false,
      "options": [
        {"label": "Postgres",        "description": "Recommended default — ACID, row-level security, good for multi-tenant"},
        {"label": "SQLite",          "description": "Single-node, edge-friendly; fine up to ~100k users"},
        {"label": "MySQL / MariaDB", "description": "Existing stack compatibility"},
        {"label": "Managed (Supabase / Clerk / Auth0 / WorkOS)", "description": "Off-load auth entirely — skill emits integration plan, not self-hosted tables"},
        {"label": "Redis (sessions only)", "description": "Paired with a primary DB for users"}
      ]
    }
  ]
}

Store as STORAGE.

1e — MFA click (AskUserQuestion, single-select)

{
  "questions": [
    {
      "question": "Multi-factor requirement?",
      "header": "MFA",
      "multiSelect": false,
      "options": [
        {"label": "None",                 "description": "Consumer app, low risk surface"},
        {"label": "TOTP (authenticator app)", "description": "RFC 6238; pair with 10 one-time recovery codes"},
        {"label": "Passkey as 2FA",       "description": "WebAuthn with user-verification=required, after password or magic link"},
        {"label": "Required for admins only", "description": "RBAC rule: role=admin → MFA gate before privileged actions"}
      ]
    }
  ]
}

Store as MFA.

Verify-criterion

  • INTAKE non-empty.
  • FLOWS has ≥1 entry.
  • STACK, STORAGE, MFA each exactly one label.
  • If FLOWS = {Passkey} ONLY and MFA = None → warn "passkey-only requires a recovery path" and return to 1b (NO DOWNGRADE: present recovery options).