# `error-codes` _(no submodules)_ ## Purpose Stable error-code registry for `@suaveplan/api-auth-rolled`. Every code is namespaced under `AUTH_ROLLED.*` so cross-package consumers (the host's audit log, the OpenAPI emitter, the conformance harness) can identify the package that raised the failure without string-matching on free-form messages. The milestone ships the session-resolver half only; the registry is correspondingly minimal — four operator-actionable infrastructure codes, all of which are thrown synchronously from production code paths and covered by the conformance test. Per-request soft failures (missing token, bad signature, expired) collapse to `null` per `SessionResolver` chain semantics and are therefore NOT codes. Account-lifecycle codes (`USER_NOT_FOUND`, `INVALID_CREDENTIALS`, `PASSWORD_BREACHED`, …) belong to the deferred provider half and will be added by a successor change. ## Features - Tagged with `defineCodes("AUTH_ROLLED", [...])` from `@suaveplan/error`, so all codes share a single namespace prefix. - `AuthRolledError` extends `SuaveplanError` so `instanceof AuthRolledError` narrows `.code` to `AuthRolledErrorCode`. - Four codes: `SIGNING_KEY_NOT_CONFIGURED` (options validation), `KEY_ROTATION_FAILED` (`TokenRotator.setKeys`), `DATABASE_REQUIRED` (missing `store`), `PRINCIPAL_PROJECTION_FAILED` (malformed user row). ## Usage: Basic ```ts import { AUTH_ROLLED_CODES, AuthRolledError } from "@suaveplan/api-auth-rolled"; throw new AuthRolledError( AUTH_ROLLED_CODES.DATABASE_REQUIRED, "host did not inject a store" ); ``` ## Usage: Advanced ```ts import { AUTH_ROLLED_CODES, AuthRolledError } from "@suaveplan/api-auth-rolled"; try { /* ... */ } catch (err) { if (err instanceof AuthRolledError) { // .rolledCode is typed as AuthRolledErrorCode — no narrowing cast. if (err.rolledCode === AUTH_ROLLED_CODES.KEY_ROTATION_FAILED) { log.fatal({ err }, "operator key-rotation contract violated"); } } throw err; } ``` ## API Reference - `AUTH_ROLLED_CODES` — frozen `Record`. - `AuthRolledErrorCode` — string-literal union of every code value. - `AuthRolledError extends SuaveplanError` — has a `rolledCode: AuthRolledErrorCode` convenience accessor. ## Implementation Notes The set of 20 codes is fixed by the OpenSpec spec delta. The conformance test enumerates `AUTH_ROLLED_CODES` and asserts every code has a named production trigger; if a code is added without a trigger, the test fails loudly. Cross-package codes (e.g. `HIBP.*` propagated from `@suaveplan/hibp` when the breach lookup fails) are NOT re-encoded — they surface to the caller intact through `SuaveplanError`'s `cause` chain so operators can attribute failures to the originating layer.