/**
 * Port: ArtifactWriter — writes run artifacts + the run manifest to external storage.
 *
 * D0033 / W0049 unifies the writer API around a single caller-facing method:
 *
 *   - `emit(type, association, payload)` — the canonical write. Dispatch on
 *     `descriptor.layout` is internal; callers never pick a shape.
 *   - `appendNdjson(type, association, rows)` — streaming-append variant used
 *     only by the `traces` artifact. Semantics differ from `emit` (repeated
 *     append vs. single-shot write) so it gets its own method rather than an
 *     overload.
 *   - `writeManifest(runId, manifest)` — writes the run manifest at
 *     `runs/{runId}/manifest.json`.
 *   - `writeBulk` / `writePerEntry` — @deprecated legacy surface retained for
 *     producer code that has not migrated to `emit`. Removal scheduled for
 *     W0052 (see `docs/decisions/D0033-unified-run-anchored-artifact-capture.md`).
 *
 * @see docs/decisions/D0032-run-anchored-artifact-store.md
 * @see docs/decisions/D0033-unified-run-anchored-artifact-capture.md
 * @see packages/core/src/artifact-registry.ts
 */
import type { ArtifactType } from "../artifact-registry.js";
import type { AssociationValues, RunId } from "../types/branded-ids.js";
import type { ArtifactRef, RunManifest } from "../types/index.js";
/**
 * An entry in a per-entry upload. The `key` is the wire-format identifier
 * (e.g. `{taskId}::{modelId}` for testOutputs); the writer sanitizes it into
 * the filename using the registry's `parseEntryKey` or direct path building.
 *
 * @deprecated Use `ArtifactWriter.emit()` with `AssociationValues` instead.
 * This type is retained for producers still on the legacy
 * `writeBulk`/`writePerEntry` path; removal scheduled for W0052.
 */
export interface ArtifactEntry<TData = unknown> {
    key: string;
    data: TData;
}
export interface ArtifactWriter {
    /**
     * Write a single artifact. The descriptor's `layout` determines whether
     * this produces a bulk object (`runs/{runId}/{slug}.{ext}`) or a per-entry
     * object (`runs/{runId}/{slug}/{entryKey}.{ext}`).
     *
     * For per-entry descriptors, `association` must carry the axis values the
     * descriptor's `formatEntryKey` consumes. For bulk descriptors, only `run`
     * is required.
     *
     * @returns `ArtifactRef` on success, or `null` when upload is skipped or
     *          fails (P5: non-blocking).
     */
    emit<T extends ArtifactType>(type: T, association: AssociationValues, payload: unknown): Promise<ArtifactRef | null>;
    /**
     * Append NDJSON rows to a per-entry artifact. Used only by `traces`, whose
     * per-entry payload is itself unbounded during production. The writer
     * buffers rows keyed on (type, entryKey) and flushes to numbered part
     * objects; the backend composes parts into the final object at trial
     * completion.
     *
     * @throws NotImplementedError on writers that don't support streaming
     *         appends (e.g. the API-gateway-backed writer; see W0052).
     */
    appendNdjson<T extends ArtifactType>(type: T, association: AssociationValues, rows: readonly unknown[]): Promise<ArtifactRef | null>;
    /**
     * Write the run manifest to `runs/{runId}/manifest.json`. Single-writer
     * per run; subsequent publishes may rewrite to append `reportIds[]`.
     */
    writeManifest(runId: RunId, manifest: RunManifest): Promise<ArtifactRef | null>;
    /**
     * @deprecated Use `emit()` with `AssociationValues` instead. Retained for
     * producers still on the legacy path; removal scheduled for W0052.
     */
    writeBulk(type: ArtifactType, runId: RunId, data: unknown): Promise<ArtifactRef | null>;
    /**
     * @deprecated Use `emit()` per entry instead. Retained for producers still
     * on the legacy path; removal scheduled for W0052.
     */
    writePerEntry(type: ArtifactType, runId: RunId, entries: readonly ArtifactEntry[]): Promise<ArtifactRef | null>;
}
/**
 * Thrown by writers that can't satisfy a method — e.g. an
 * `ApiGatewayArtifactWriter` cannot implement `appendNdjson` until the batch
 * signing endpoint (W0052) lands. Callers should treat this as an explicit
 * failure rather than a silent no-op so the gap surfaces in logs.
 */
export declare class NotImplementedError extends Error {
    constructor(message: string);
}
/** No-op writer — every method returns null. Used when no storage is configured. */
export declare class NoOpArtifactWriter implements ArtifactWriter {
    emit(): Promise<null>;
    appendNdjson(): Promise<null>;
    writeManifest(): Promise<null>;
    writeBulk(): Promise<null>;
    writePerEntry(): Promise<null>;
}
