/**
 * Source- and resource-tagged locator family (D0063, generalizing D0062).
 *
 * A {@link DocumentRef} records *what* a document is (its id, slug, title); a
 * locator records *where it lives and how to re-fetch it*. D0062 introduced the
 * locator for documents; D0063 generalizes it on a SECOND orthogonal axis so the
 * same substrate can locate content *releases* without cloning the document
 * machinery.
 *
 * Two orthogonal taxonomies:
 * - the backend `kind` axis — *which content system* ({@link SourceKind}:
 *   `sanity-content-lake`; future `google-drive`);
 * - the `resource` axis — *what kind of thing inside that backend*
 *   ({@link ResourceKind}: `document`, `release`; future), nested UNDER `kind`.
 *
 * A release is therefore NOT a new `SourceKind` — it lives inside the
 * `sanity-content-lake` backend as a perspective, sharing the same
 * `{projectId, dataset}` anchor and swapping the identity axis from
 * `documentId`+`revision` to `releaseName`. The existing
 * {@link SanityContentLakeLocator} becomes the `resource: "document"` case with
 * the discriminant OPTIONAL (absent ⇒ document), so every already-persisted
 * immutable locator type-checks unchanged. {@link SourceLocator} stays frozen as
 * the document-arm alias — zero churn for its existing consumers (doc-fetcher
 * port, DocumentRef, projections).
 *
 * Full design: docs/design-docs/resource-locator.md.
 */
import type { DocumentRef } from "./document-ref.js";
import type { ReleaseRef } from "./release-ref.js";
/**
 * Default Sanity project AILF reads documentation from.
 *
 * Promoted here so {@link resolveLocator} and both consumers (the eval source
 * resolver and the dashboard `sanity-config`) agree on one value instead of
 * duplicating the literal. Project `3do82whm` hosts the `next` docs dataset.
 */
export declare const DEFAULT_DOCS_PROJECT_ID = "3do82whm";
/** Default Sanity dataset AILF reads documentation from. */
export declare const DEFAULT_DOCS_DATASET = "next";
/**
 * The content systems AILF can source a resource from — the *backend* axis.
 * Hyphenated kebab-case, matching the eval-side `DocSourceConfig.kind` taxonomy.
 */
export type SourceKind = "sanity-content-lake" | "google-drive";
/**
 * The kind of thing referenced *within* a backend — the orthogonal `resource`
 * axis nested under {@link SourceKind}. Absent on a document locator ⇒
 * `"document"`; a release lives inside the Content Lake backend, it is not a
 * sibling backend. Open for future variants (e.g. a Drive `"folder"`).
 */
export type ResourceKind = "document" | "release";
/**
 * WHERE a resource lives + tenant scope. Backend-tagged; per-backend fields live
 * here so both resource arms (document, release) share one anchor instead of
 * repeating `projectId`/`dataset`/`organizationId` on each.
 */
export interface SanityContentLakeAnchor {
    kind: "sanity-content-lake";
    /** Sanity project the resource lives in. */
    projectId: string;
    /** Dataset the resource lives in. */
    dataset: string;
    /**
     * Org the project belongs to. Optional — absent ⇒ org-dependent affordances
     * (cross-org deep links) gracefully disengage. Derivable from `projectId` via
     * the management API, so it's denormalization, not identity.
     */
    organizationId?: string;
    /** Canonical public/read URL, when one exists. */
    url?: string;
}
/**
 * Coordinates for a *document* stored in a Sanity Content Lake dataset — the
 * D0062 locator, now expressed as the `resource: "document"` arm of the
 * {@link ResourceLocator} union. `resource` is OPTIONAL (absent ⇒ document), so
 * every already-persisted document locator type-checks unchanged (additive).
 */
export interface SanityContentLakeLocator extends SanityContentLakeAnchor {
    /** Resource axis; absent ⇒ `"document"`. */
    resource?: "document";
    /** Sanity document id (published id; no `drafts.` prefix). */
    documentId: string;
    /** Content revision at read time (staleness / reproducibility). */
    revision?: string;
    /** Release/perspective the document was read under; omit ⇒ `"published"`. */
    perspective?: string;
}
/**
 * Coordinates for a *content release* in a Sanity Content Lake dataset — the
 * `resource: "release"` arm. Shares the anchor with the document arm and swaps
 * the identity axis to `releaseName`.
 */
export interface SanityReleaseLocator extends SanityContentLakeAnchor {
    resource: "release";
    /**
     * Release id == `system.release` `name` == the perspective string. The
     * `_.releases.<name>` doc id and `versions.<name>.*` member ids all derive
     * from this one value.
     */
    releaseName: string;
}
/**
 * Coordinates for a *file* in Google Drive — the `kind: "google-drive"` document
 * arm (D0063's reserved second-backend seam). `fileId` is the re-fetch handle;
 * the human-facing Drive URL derives from it, so it isn't persisted. No
 * project/dataset anchor — Drive has neither.
 */
export interface GoogleDriveLocator {
    kind: "google-drive";
    fileId: string;
    /** Drive `version` at read time (staleness / reproducibility). */
    revision?: string;
}
/**
 * A source- and resource-tagged retrieval contract: which backend a resource
 * lives in, what kind of resource it is, and the coordinates needed to
 * re-fetch it. The generalized umbrella the shared machinery ranges over.
 */
export type ResourceLocator = SanityContentLakeLocator | SanityReleaseLocator | GoogleDriveLocator;
/**
 * The document arm across backends — what a {@link DocumentRef} holds: a Content
 * Lake document (D0062) or a Google Drive file (D0063). Release locators are
 * excluded; those live only on a `ReleaseRef`.
 */
export type SourceLocator = SanityContentLakeLocator | GoogleDriveLocator;
/**
 * Give EVERY ref — new or legacy — a locator.
 *
 * A ref carrying an explicit `locator` returns it verbatim. A legacy ref
 * (written before this feature, so without a locator — and an immutable report
 * can never be backfilled) resolves to a `sanity-content-lake` locator built
 * from the default docs source. Because there is exactly one docs source today,
 * the synthesized default is correct for 100% of historical reports; only new
 * reports from a second source need to carry an explicit locator. This is what
 * lets consumers treat all reports uniformly without backfilling history.
 */
export declare function resolveLocator(ref: DocumentRef): SourceLocator;
/**
 * The symmetric twin of {@link resolveLocator} for releases. Shares the anchor
 * default; the synthesis body differs only because it reads a different identity
 * field (`releaseName` instead of `documentId`+`revision`) — irreducible, not
 * duplication. A ref carrying an explicit `locator` returns it verbatim.
 */
export declare function resolveReleaseLocator(ref: ReleaseRef): SanityReleaseLocator;
/**
 * Turn a locator into Sanity client / App SDK read params, or `null` for a
 * backend that isn't Sanity — the caller handles non-Sanity origins explicitly.
 * The resource axis forks only the perspective derivation: a release reads under
 * its `releaseName`; a document reads under its `perspective` (defaulting to
 * `"published"` when omitted).
 */
export declare function toSanityClientConfig(loc: ResourceLocator): {
    projectId: string;
    dataset: string;
    perspective: string;
} | null;
/** Narrow a {@link ResourceLocator} to the release arm. */
export declare const isReleaseLocator: (loc: ResourceLocator) => loc is SanityReleaseLocator;
/** Narrow a {@link ResourceLocator} to the Sanity document arm (resource absent ⇒ document). */
export declare const isDocumentLocator: (loc: ResourceLocator) => loc is SanityContentLakeLocator;
/** Compose the `system.release` document id from a release name. */
export declare const buildReleaseDocumentId: (name: string) => string;
/** Recover a release name from its `_.releases.<name>` document id. */
export declare const releaseNameFromDocumentId: (id: string) => string;
/**
 * Compose the release-version document id an Agent Actions `transform` targets:
 * `versions.<releaseName>.<publishedId>`. The service treats a `versions.…` id
 * as `forcePublishedWrite` — it mutates only this version, never the published
 * document.
 */
export declare const buildVersionDocumentId: (releaseName: string, publishedId: string) => string;
/**
 * Construct the shared Content Lake anchor from resolved source coordinates,
 * falling back to the default docs source. The single anchor-construction
 * source of truth shared by the document locator builder (eval's
 * `buildSanityLocator`) and {@link buildSanityReleaseLocator}. `organizationId`
 * is omitted (not emitted as `undefined`) when the source lacks it, so anchors
 * compare and persist cleanly.
 */
export declare function buildSanityAnchor(source?: {
    projectId?: string;
    dataset?: string;
    organizationId?: string;
}): SanityContentLakeAnchor;
/** Stamp a full release locator from resolved coordinates + a release name. */
export declare function buildSanityReleaseLocator(source: {
    projectId?: string;
    dataset?: string;
    organizationId?: string;
} | undefined, releaseName: string): SanityReleaseLocator;
/**
 * Package a report's loose `provenance.source` siblings into a canonical
 * {@link ReleaseRef}. A read-time normalizer: the run-release coordinates
 * already persist on the report (`RunContext.source`), so the report→release
 * relationship needs no producer or persistence change. Returns `null` when no
 * release perspective is set — the non-release perspectives (`"published"`,
 * `"raw"`, `"drafts"`) are not releases.
 */
export declare function deriveRunReleaseRef(source: {
    projectId?: string;
    dataset?: string;
    perspective?: string;
}): ReleaseRef | null;
/**
 * Exhaustiveness guard. Every match over the {@link ResourceLocator} union ends
 * in `default: return assertNever(loc)`, so adding a future `resource`/`kind`
 * that some code site forgot to handle is a compile error, not a silent runtime
 * bug.
 */
export declare function assertNever(x: never): never;
