/** * #709 ground-truth deriver — slice 5d-ii: the live held-out disposition adapter. * * Fetches a HELD-OUT corpus PR's review threads WITH span anchoring (the comment * `diffHunk` + the thread line) — the data slice 5d-iii binds a `RuleFiring`'s * matched line to a disposition by content/invariant. Distinct from the mining * `ReviewThreadSourceAdapter` (which fetches TRAIN PRs and carries no span): the * answer key labels HELD-OUT firings, so it needs the held-out PRs' threads, * span-anchored, and a richer `CorpusDisposition` payload (core schema). * * Like the mining adapter, this SURFACES `isResolved`/`isOutdated` and never * filters on them (the #2201 "surface, don't filter" discipline; the taxonomy + * span-bind decide, 5d-i/5d-iii). Unlike it, a fetch failure FAILS LOUD: the * disposition freeze is a by-hand, all-or-nothing producer step (a silent skip * would under-populate the answer-key provenance), so a network/parse/pagination * fault throws a structured TotemError rather than a discriminated skip. * * CI HARD-GATE (agy panel): a live GitHub fetch must NEVER run in CI — the * certifying run is zero-network and reads only the FROZEN `corpus-dispositions.json`. * `fetch` throws if `CI` is set without an explicit `ALLOW_LIVE_FETCH` escape, so * an accidental test/CI invocation fails loud instead of hitting the network. * * Reuses the established `gh` CLI exec pattern (Tenet-21 — no bespoke GraphQL * client). The `exec` seam is injectable so the query-spy + mapping + CI-gate * tests run fully offline. */ import { z } from 'zod'; import type { CorpusDisposition, CorpusDispositionThread } from '@mmnto/totem'; import type { GhExec } from './spine-review-thread-source.js'; declare const GqlThreadSchema: z.ZodObject<{ id: z.ZodString; isResolved: z.ZodBoolean; isOutdated: z.ZodBoolean; path: z.ZodString; line: z.ZodNullable; originalLine: z.ZodNullable; comments: z.ZodObject<{ pageInfo: z.ZodObject<{ hasNextPage: z.ZodBoolean; }, "strip", z.ZodTypeAny, { hasNextPage: boolean; }, { hasNextPage: boolean; }>; nodes: z.ZodArray; diffHunk: z.ZodNullable; author: z.ZodNullable>; body: z.ZodString; }, "strip", z.ZodTypeAny, { body: string; author: { login: string; } | null; databaseId: number | null; diffHunk: string | null; }, { body: string; author: { login: string; } | null; databaseId: number | null; diffHunk: string | null; }>, "many">; }, "strip", z.ZodTypeAny, { pageInfo: { hasNextPage: boolean; }; nodes: { body: string; author: { login: string; } | null; databaseId: number | null; diffHunk: string | null; }[]; }, { pageInfo: { hasNextPage: boolean; }; nodes: { body: string; author: { login: string; } | null; databaseId: number | null; diffHunk: string | null; }[]; }>; }, "strip", z.ZodTypeAny, { path: string; line: number | null; id: string; comments: { pageInfo: { hasNextPage: boolean; }; nodes: { body: string; author: { login: string; } | null; databaseId: number | null; diffHunk: string | null; }[]; }; isResolved: boolean; isOutdated: boolean; originalLine: number | null; }, { path: string; line: number | null; id: string; comments: { pageInfo: { hasNextPage: boolean; }; nodes: { body: string; author: { login: string; } | null; databaseId: number | null; diffHunk: string | null; }[]; }; isResolved: boolean; isOutdated: boolean; originalLine: number | null; }>; /** * Build the held-out `reviewThreads` GraphQL query. ADDITIVELY requests the span * anchors (`line`, `originalLine`, comment `diffHunk`) + the audit ids * (`thread.id`, comment `databaseId`) on top of the mining query's * `isResolved`/`isOutdated`/`path`/`author`/`body`. It deliberately does NOT add * an `isResolved: false` server filter (the "surface, don't filter" ruling). * Exported for the query-spy test. */ export declare function buildCorpusDispositionsQuery(owner: string, name: string, pr: number): string; /** * Map validated GraphQL thread nodes to `CorpusDispositionThread[]`. The thread's * span source `diffHunk` is the ROOT (first) comment's hunk — the finding's * anchor; a thread with no comments carries ''. A null author (deleted/ghost) * coerces to '' (a non-bot empty author core's logic handles). Pure — exported * for the mapping test. */ export declare function mapDispositionThreads(nodes: z.infer[]): CorpusDispositionThread[]; export interface CorpusDispositionSourceOptions { owner: string; name: string; cwd?: string; /** Injectable exec seam (tests). Defaults to a `gh`-backed `safeExec`. */ exec?: GhExec; /** Process env (injected in tests) — the CI hard-gate reads it. Defaults to `process.env`. */ env?: NodeJS.ProcessEnv; } /** * The live held-out `corpus-dispositions` source. By-hand producer-time only * (never CI — the hard-gate enforces it). `fetch` throws loud on any fault. */ export declare class CorpusDispositionSourceAdapter { private readonly owner; private readonly name; private readonly cwd; private readonly env; private readonly injectedExec; private execPromise; constructor(opts: CorpusDispositionSourceOptions); private resolveExec; fetch(pr: number): Promise; } export {}; //# sourceMappingURL=spine-corpus-disposition-source.d.ts.map