/**
 * @sanity/ailf-core — Shared team-resolution helper + registration error builder.
 *
 * External task registration (mirroring a cross-repo task suite into Content
 * Lake) is gated on the caller's `owner.team` resolving to an *active*
 * `ailf.team`. Two server surfaces enforce that gate — the API gateway
 * pre-flight (`packages/api`, synchronous HTTP 422) and the pipeline mirror
 * step (`packages/eval`, fail-fast abort) — and both must produce an identical,
 * caller-actionable error. To keep them from drifting, the team lookup and the
 * error wording live here, in one place both import.
 *
 * Why core (not eval): `packages/api` cannot import from `@sanity/ailf` (the
 * eval package) per the api-gateway rule, but it can depend on
 * `@sanity/ailf-core`. This is the same engines-in-core rationale as D0048.
 *
 * `resolveActiveTeam` performs I/O, so it takes the Sanity client as a
 * parameter (the gateway and the pipeline each pass their own, configured for
 * the `ailf-prod-private` dataset). The parameter is typed structurally
 * ({@link TeamLookupClient}) rather than as `@sanity/client`'s `SanityClient`,
 * so this package stays the dependency-graph leaf it is meant to be (it depends
 * only on `@sanity/ailf-shared` and `zod`). A real `SanityClient` satisfies the
 * interface; a test fake does too.
 *
 * @see docs/superpowers/specs/2026-06-15-external-task-registration-design.md (§6)
 * @see docs/decisions/D0055-team-entity-ownership-subscription-split.md
 * @see packages/shared/src/registration.ts — the cross-cut constants
 */
/**
 * The minimal slice of a Sanity client this helper needs: a single
 * GROQ `fetch`. `@sanity/client`'s `SanityClient` is assignable to this (its
 * `fetch` accepts the same `(query, params?)` and an extra optional `options`),
 * and so is any test double. Defining it here avoids a hard dependency on
 * `@sanity/client` from `@sanity/ailf-core`.
 */
export interface TeamLookupClient {
    fetch<R = unknown>(query: string, params?: Record<string, unknown>): Promise<R>;
}
/**
 * The outcome of resolving an `owner.team` slug against the team registry.
 * `active` is the only status that permits registration; `archived` and
 * `absent` are kept distinct so callers can tailor diagnostics even though both
 * refuse the gate. `slug` is the normalized (alias-folded) slug that was looked
 * up; `teamId` is the `ailf.team.<slug>` document id, present whenever a
 * document was found.
 */
export type ResolveActiveTeamResult = {
    status: "active";
    teamId: string;
    slug: string;
} | {
    status: "archived";
    teamId: string;
    slug: string;
} | {
    status: "absent";
    slug: string;
};
/**
 * Resolve an `owner.team` slug to an active / archived / absent verdict.
 *
 * The slug is normalized first (trim, lowercase, alias fold via
 * {@link normalizeOwnerTeam}), so `core-docs` resolves the `docs` team. An
 * empty or `"unknown"` slug short-circuits to `absent` without a query — there
 * is no team to find. A row that fails {@link TeamLookupRowSchema} is treated
 * as `absent` (conservative: never register against a malformed team).
 */
export declare function resolveActiveTeam(slug: string, client: TeamLookupClient): Promise<ResolveActiveTeamResult>;
/** Stable, machine-readable registration-failure codes (spec §6, surfaced as HTTP 422). */
export type RegistrationErrorCode = "registration_team_not_found" | "registration_area_team_conflict" | "registration_no_tasks";
/**
 * The structured registration error both surfaces return. `message` states the
 * specific problem; `remediation` is the shared {@link REGISTRATION_REMEDIATION}
 * prose; `team` echoes the caller's declared team slug.
 */
export interface RegistrationError {
    code: RegistrationErrorCode;
    message: string;
    remediation: string;
    team: string;
}
/**
 * The context each code needs to compose its message. The extra fields on the
 * area-conflict variant feed the message only — the output shape stays the flat
 * {@link RegistrationError}.
 */
export type RegistrationErrorInput = {
    code: "registration_team_not_found";
    team: string;
} | {
    code: "registration_no_tasks";
    team: string;
} | {
    code: "registration_area_team_conflict";
    team: string;
    area: string;
    existingTeam: string;
};
/**
 * Build the structured error for a refused registration. The single source of
 * truth for registration failure wording — both the gateway pre-flight and the
 * pipeline mirror step call this, so the caller sees the same `code`, `message`,
 * and `remediation` whichever surface refuses.
 */
export declare function buildRegistrationError(input: RegistrationErrorInput): RegistrationError;
