/**
 * GcsRunArtifactReader — reads run manifests and artifact payloads back from
 * `gs://ailf-artifacts`, the read-side counterpart of `GcsArtifactWriter`
 * (D0091).
 *
 * The fact-loader engine talks only to the `RunArtifactReader` port, so this
 * adapter is the single place that knows about GCS object layout. It resolves
 * paths from the manifest the writer produced:
 *   - bulk artifacts live at the single object `ref.path`;
 *   - per-entry artifacts live at `{ref.path}/{sanitizedKey}.{ext}`, one object
 *     per catalog entry.
 *
 * `ref.path` is authoritative for resolution (D0040/W0135): a cache-inherited
 * artifact carries a `sourceRunId` and its `path` already points at the origin
 * run's prefix, so the reader extracts the storage run from `ref.path` and
 * rebuilds the object path via the registry's `objectPath` builder rather than
 * assuming the requesting run's prefix.
 *
 * Payloads are JSON-deserialized (or NDJSON-split) to `unknown` — structural
 * parse only. The descriptor's `rowSchema` validates the extractor's output
 * downstream (the engine's D0045 trust boundary); the reader never coerces.
 *
 * Beyond the two port methods, `listCandidateRuns` resolves the loader's work
 * list straight from GCS — the run prefixes whose manifest records a
 * `reportSnapshot` — so the loader is independent of Airbyte.
 *
 * All network I/O runs under a shared {@link ConcurrencyLimiter}, mirroring the
 * writer, so a backfill fanning over hundreds of runs stays within the GCS
 * connection pool and per-prefix quota.
 *
 * @see docs/decisions/D0091-bigquery-analytics-fact-loader.md
 * @see packages/eval/src/artifact-capture/gcs-artifact-writer.ts
 */
import { Storage } from "@google-cloud/storage";
import { type ArtifactType, type ParsedArtifactEntry, type RunArtifactReader, type RunId, type RunManifest } from "../_vendor/ailf-core/index.d.ts";
/** Options for constructing a {@link GcsRunArtifactReader}. */
export interface GcsRunArtifactReaderOptions {
    /** GCS bucket the artifacts live in (e.g. "ailf-artifacts"). */
    bucket: string;
    /**
     * Pre-constructed Storage client. When omitted the reader constructs one
     * lazily from Application Default Credentials. Tests supply a fake here to
     * avoid real network calls.
     */
    storage?: Storage;
    /**
     * Bound on concurrent GCS reads. Defaults to 8 — the same effective
     * concurrency the artifact writer measured safe.
     */
    concurrency?: number;
}
/**
 * Reads a run's manifest and declared artifact payloads from GCS. Implements
 * the {@link RunArtifactReader} port and adds {@link listCandidateRuns} for
 * building the loader's work list.
 */
export declare class GcsRunArtifactReader implements RunArtifactReader {
    private client;
    private readonly bucket;
    private readonly limiter;
    /**
     * Per-run manifest memo. Both `readManifest` and every `readArtifact` call
     * for a run share one fetch — the engine reads the manifest then fetches
     * several artifact types per run, so this collapses N+1 GETs to one.
     * Manifests are immutable once finalized, so caching for the process
     * lifetime is safe. A rejected fetch stays rejected (the run is skipped).
     */
    private readonly manifestCache;
    constructor(options: GcsRunArtifactReaderOptions);
    readManifest(runId: RunId): Promise<RunManifest>;
    readArtifact(runId: RunId, type: ArtifactType): Promise<readonly ParsedArtifactEntry[]>;
    /**
     * The loader's candidate runs: every run prefix under `runs/` whose manifest
     * records a `reportSnapshot` (i.e. the run published a report). Resolved
     * straight from GCS so the loader does not depend on Airbyte. Runs whose
     * manifest is missing or unreadable are skipped silently — a corrupt run is
     * not a candidate, and per-run parse failures surface later in the engine.
     */
    listCandidateRuns(): Promise<RunId[]>;
    private getManifest;
    private fetchManifest;
    /**
     * Download and deserialize one artifact object. Dispatches on the
     * descriptor's declared mime so JSON bulks parse whole, NDJSON per-entry
     * streams parse into a row array, and text formats (markdown/yaml) return the
     * raw string. Throws on a present-but-unreadable object (the engine isolates
     * the run).
     */
    private downloadBody;
    /** Raw object download to a UTF-8 string, bounded by the limiter. */
    private download;
    /** List the immediate `runs/{runId}/` prefixes via a delimiter query. */
    private listRunPrefixes;
    private getClient;
}
