/**
 * Composition Root — the single place that knows about all concrete adapters.
 *
 * Creates a fully wired AppContext from resolved configuration.
 * This function is called ONCE per CLI invocation, at the top of each
 * command's action handler.
 *
 * Design principle: no DI container, no decorators, no reflection.
 * Just a plain factory function that builds a plain object.
 *
 * Why this exists:
 * - Before: each command constructs its own adapters (scattered coupling)
 * - After: one factory, one place to change adapter wiring
 *
 * @see packages/core/src/ports/context.ts — AppContext interface
 * @see docs/archive/exec-plans/ports-and-adapters/phase-7-composition-root.md
 */
import { type AppContext, type ArtifactWriter, type ArtifactWriterProgressOptions, type AssertionRegistration, type CardRegistry, type DiagnosisRunner, type Logger, type ResolvedConfig, type WriteSource } from "./_vendor/ailf-core/index.d.ts";
export type { LLMClientKeys } from "./_vendor/ailf-core/index.d.ts";
import { type BorderlineConsensusOptions, type BorderlineConsensusResult } from "./pipeline/borderline-consensus-runner.js";
import { CompositeTaskSource, ContentLakeTaskSource, RepoTaskSource } from "./adapters/task-sources/index.js";
import { type KnownDocSourceConfig } from "./adapters/doc-fetchers/source-kinds.js";
/**
 * Create a fully wired AppContext from resolved configuration.
 *
 * Every adapter is constructed here and nowhere else (outside of tests).
 * Swapping an adapter is a one-line change in this function.
 */
export declare function createAppContext(config: ResolvedConfig): AppContext;
/**
 * Selects the `ArtifactWriter` wiring per D0033 M4:
 *
 *   1. `--no-artifacts` (`config.artifactsDisabled === true`, or legacy
 *      `config.artifactUpload === false`) → `NoOpArtifactWriter`.
 *   2. Otherwise: always attach `LocalFilesystemArtifactWriter` under
 *      `--artifacts-dir` (default `.ailf/results/captures`).
 *   3. When a remote backend is reachable (ADC, GCLOUD_PROJECT, or an
 *      AILF API key + URL), layer it via `FanoutArtifactWriter([local, gcs])`.
 *      Local is listed first so a local success + remote failure still
 *      produces a non-null ref.
 *
 * Always returns a writer — pipeline code can assume `ctx.artifactWriter`
 * is present. Producers post-W0050 drop their `if (ctx.artifactWriter)`
 * guards in Slice 6.
 *
 * Exported for unit-test access; not part of the public package API.
 */
export declare function createArtifactWriter(config: ResolvedConfig, logger: Logger, progress?: ArtifactWriterProgressOptions, writerSource?: WriteSource): ArtifactWriter;
/**
 * Build the `TaskSource` adapter wired by the composition root for a
 * given `ResolvedConfig`. Exported for test access — composition-root
 * wiring is a contract worth asserting directly.
 */
export declare function createTaskSource(config: ResolvedConfig): CompositeTaskSource | ContentLakeTaskSource | RepoTaskSource;
/**
 * Generic Promptfoo assertion types available to all evaluation modes.
 *
 * These are evaluation primitives (text matching, JSON validation, LLM grading)
 * that aren't specific to any mode or domain. They're registered before any
 * preset so every mode has access to them.
 *
 * `compatibleModes` is omitted — when undefined, the assertion is compatible
 * with all modes. Mode-specific assertions can be registered by presets with
 * explicit mode whitelists.
 */
export declare const FRAMEWORK_ASSERTIONS: AssertionRegistration[];
/**
 * Resolve the active source from `config/sources.ts` (W0215).
 *
 * Matches by `name` when a source is requested. With no `--source`, picks the
 * entry explicitly tagged `default: true`; when none is tagged it falls back to
 * the built-in Sanity default rather than an arbitrary first entry.
 * `config/sources` is additive over the implicit Sanity source
 * (production/branch/local live in the preset, not here), so a lone non-default
 * entry must not silently become the default. Untagged entries default to
 * `kind: "sanity-content-lake"` (backward compat). When no config file exists,
 * returns a stub Sanity entry — preset factories that ignore the source (Sanity)
 * still work; factories that require source fields (Drive) fail loudly at
 * construction with a clear missing-field error.
 *
 * Exported for test access.
 */
export declare function resolveSourceEntry(sourceName: string | undefined, rootDir: string): KnownDocSourceConfig;
/**
 * Severity boundaries from `packages/eval/config/thresholds.ts`
 * (severity.critical/warning/info `composite-below` at L50/54/58 — 30, 50,
 * 60). The borderline detector flags a judgment when its score is within
 * ±5 of any of these. Composition-root reads them ONCE and threads the
 * typed `readonly number[]` into `runBorderlineConsensus` rather than
 * re-deriving them at each call site (Pitfall 5 — single source of truth
 * for the scale).
 */
export declare const BORDERLINE_SEVERITY_THRESHOLDS: readonly number[];
/**
 * Default replications per borderline judgment when the caller's
 * `RepoConfig.execution.borderlineReplications` is unset (locked answer
 * #4 in plan 03-04). Three replications + the original score = four
 * scores per consistency record, which is the minimum that produces a
 * non-degenerate stdDev / median split.
 */
export declare const DEFAULT_BORDERLINE_REPLICATIONS = 3;
/**
 * Factory for the borderline-consensus runner. Returns a function that
 * applies the severity-threshold and replication defaults from
 * composition-root, leaving the live grader entry point (the `regrade`
 * callback) and the candidate `judgments` array as runtime inputs.
 *
 * The pipeline-side caller (currently `pipeline/calculate-scores.ts`'s
 * post-extraction junction) supplies the `regrade` callback that maps a
 * `GraderJudgment` to a fresh score via the response/rubric text from
 * the original Promptfoo result. See the runner's header for the
 * rationale on injecting the regrader rather than calling `gradeOnce`
 * inline (Pitfall 6 — preserve the runner's purity wrt the existing
 * grader-comparison split).
 */
export declare function createBorderlineConsensusRunner(opts: {
    borderlineReplications?: number;
}): (args: Pick<BorderlineConsensusOptions, "judgments" | "logger" | "regrade">) => Promise<BorderlineConsensusResult>;
/**
 * Returns the full 8-card `CardRegistry` backed by `DIAGNOSIS_CARD_GENERATORS`
 * from `@sanity/ailf-core`. Exposed as a function (not a module-level const)
 * so the composition root remains the single-seam factory and tests can assert
 * the call site (AI-SPEC §3 Pitfall 1 — no module-scope mutables).
 */
export declare function buildDiagnosisRegistry(): CardRegistry;
/**
 * Build a fully-wired `DiagnosisRunner` from an `AppContext`.
 *
 * Wires the full 8-card registry, `loadAttributions` bound to the local
 * filesystem (Phase-4 per-entry attribution objects at
 * `{artifactsDir}/runs/{runId}/attribution/*.json`), and the real
 * `diagnosisWriter` that emits the Diagnosis through a post-hoc-flagged
 * artifact writer AND patches the report doc's
 * `summary.artifactManifest.diagnosis` slot. Two steps because `ailf interpret`
 * runs after the report doc has already been published — the pipeline path's
 * publish-report-step.ts:187 lifts the in-memory run manifest into the doc at
 * end-of-run, but that step never fires for a deferred command.
 *
 * The post-hoc writer is built with `writerSource: "post-hoc"` so the D0050
 * guard accepts the diagnosis descriptor (`writePolicy: "post-hoc"`). Without
 * this, every emit would be rejected at runtime.
 *
 * `diagnosisReader` is still a no-op shim: the Studio data path uses the
 * artifact-manifest entry (populated by the writer + patch) plus a signed-URL
 * fetch, so reader-side cache wiring is deferred to a follow-up W-item.
 * Without the reader, `ailf interpret --refresh` cache hits are not yet served
 * from GCS — they recompute.
 *
 * Plan-06 API/CLI consumers import this function from the composition root
 * and pass `ctx` from `createAppContext(config)`.
 */
export declare function getDiagnosisRunner(ctx: AppContext, opts?: {
    artifactWriter?: ArtifactWriter;
}): DiagnosisRunner;
