Replace the single mutable-context Pipeline with a two-phase, condition-driven
system dispatched by token type.
New architecture:
- TokenType(StrEnum) replaces source: str on AuthContext / TokenKind
- AuthPipeline: pure prepare→auth step runner; no guard()
- PipelineRoute: binds AuthPipeline to an optional required_edition gate
- PipelineRouter: single guard() entry point; runs edition/license/token-type
pre-gates then dispatches to the registered pipeline for the token type
- Cond / When: composable predicates for conditional step dispatch
- AuthData: frozen Pydantic model produced by the prepare phase; carries
token_id so endpoints don't need to call get_auth_ctx() for identity fields
- Edition enum + current_edition(): CE / EE / SAAS discriminator
Two pipelines in composition.py:
- account_pipeline — OAUTH_ACCOUNT tokens
- external_sso_pipeline — OAUTH_EXTERNAL_SSO tokens (EE enforced at route level)
All /openapi/v1 endpoints migrated to auth_router.guard().
Old context.py, steps.py, strategies.py, surface_gate.py deleted.
WORKSPACE_READ scope added; cached_verdicts renamed to membership_cache.