import type { ChecklistRevision } from "../eval/label/types.js"; import { type Annotation, type Annotator, type ChecklistAnnotation, type RunPayload, type Score, type ScorePoint } from "./annotations.js"; import { type CodeAttachmentPlan } from "./attachCode.js"; import { type WorkdirAttachmentRequest } from "./attachWorkdir.js"; import { type Comment, type CommentDraft } from "./comments.js"; import { type StatelogMergePlan } from "./mergeStatelog.js"; import { type RunDirectorySnapshot } from "./runDir.js"; /** * The public writes on a run directory. Each operation describes a domain * change; the lock, the preflight, the torn-tail repair, and the order of * writes are this module's business and nobody else's. Every operation: * * 1. takes the writer lock, * 2. reads one snapshot, * 3. plans the WHOLE request with the pure planners — any refusal throws * before a byte is written, * 4. repairs a torn final line on each append target, * 5. applies, then re-reads and returns the fresh snapshot, * 6. releases the lock, on success or failure. */ export type { WorkdirAttachmentRequest }; export type MutationOptions = { reportWarning?(message: string): void; /** Injected clock for tests. */ now?(): string; }; export type WrapTracesRequest = { /** The group directory; one `//` is written per trace. */ groupDir: string; statelogFiles: string[]; /** Keep only this trace (full id or unique prefix). */ trace?: string; codeEntries: string[]; workdir?: WorkdirAttachmentRequest; annotationFiles: string[]; }; export type WrapTracesResult = { written: string[]; skipped: { traceId: string; reason: string; }[]; }; /** * `agency runs add` and `agency run --capture-workdir`: make one run directory * per trace in the given statelogs, under `groupDir`. Each child is assembled * below `/.staging/` and renamed into place, so a child is * either whole or absent. A child that already exists is skipped, never * touched. Code is attached to the traces that recorded its closure hash and * must match at least one; annotation rows go to the child their `traceId` * names and must each name one of the traces. */ export declare function wrapTracesAsRunDirectories(request: WrapTracesRequest, options?: MutationOptions): WrapTracesResult; export type RunAnnotationDraft = { traceId: string; annotator: Annotator; payload: RunPayload; }; export type RecordCompletedRunRequest = { dir: string; /** Absent when the run never wrote a statelog; the `run` row is still * recorded so the failure is not lost. */ stagedStatelogFile?: string; codeEntry?: string; workdir?: WorkdirAttachmentRequest; /** Files to store under `graders/` (content-hash names); the run row's * `graders` field says what they are. */ gradersFiles?: { name: string; content: string; }[]; run: RunAnnotationDraft; }; export type RecordCompletedRunResult = { annotation: Annotation; snapshot: RunDirectorySnapshot; }; /** The eval harness's one call per finished test, on a fresh directory: * write the staged statelog, attach code and workdir, append the `run` row. */ export declare function recordCompletedRun(request: RecordCompletedRunRequest, options?: MutationOptions): RecordCompletedRunResult; export type ScoreDraft = { traceId: string; annotator: Annotator; name: string; score: Score; weight: number; mustPass: boolean; feedback?: string; points?: ScorePoint[]; gradersModule?: string; goal?: string; }; export type RecordGradingPassRequest = { dir: string; scores: ScoreDraft[]; }; export type RecordGradingPassResult = { passId: string; annotations: Annotation[]; snapshot: RunDirectorySnapshot; }; /** One grading pass: every score draft gets the same fresh `passId` and the * pass size. A crash before the last row leaves an incomplete pass the fold * ignores. */ export declare function recordGradingPass(request: RecordGradingPassRequest, options?: MutationOptions): RecordGradingPassResult; export declare function newPassId(): string; export type RecordChecklistRowRequest = { dir: string; /** The group the run belongs to: where the checklist lineage lives. */ groupDir: string; row: ChecklistAnnotation; }; export type RecordChecklistRowResult = { outcome: "appended" | "replayed"; snapshot: RunDirectorySnapshot; }; /** One labeling sign-off on one run: the row exactly as the session built it * (its id is already derived from its content, so a replay lands on the same * id), grounded against the run and the group's lineage immediately before an * idempotent append under the run's lock. */ export declare function recordChecklistRow(request: RecordChecklistRowRequest, options?: MutationOptions): RecordChecklistRowResult; /** A row's hash must be the revision's, and every answered question must be * one that revision defines; otherwise the per-question fold would be * reading answers nobody could have given. */ export declare function assertRowMatchesRevision(row: ChecklistAnnotation, revision: ChecklistRevision): void; /** * Append one comment as a durable line, under the lock the comments path * decides (`commentsLockFor`): a run directory's `.lock`, or `.lock` * for a loose statelog. No snapshot is taken, since a comment is about one row * and validates nothing against the trace; `withWriter` would parse the * statelog twice to append one line. Only `commentsStore.ts` calls this. */ export declare function appendCommentRow(commentsPath: string, draft: CommentDraft, options?: MutationOptions): Comment; export type { CodeAttachmentPlan, StatelogMergePlan };