import { z } from 'zod'; import { type EvidenceBrief } from './crystallization-types.js'; /** * EvidenceBriefBuilder — spec §4.7 / §10 RL-7. * * The brief is a 4-section natural-language projection that MUST * accompany every user-facing recommendation. The shape guard is * encoded in `EvidenceBriefSchema` (see crystallization-types.ts); * this module is the LLM-side entry point that PRODUCES the brief * from a finished trace + evaluator summary and the validator that * REFUSES to render a recommendation payload without all 4 sections. * * Hard rules (mirrored from spec): * * 1. Every section must be a non-empty NL string (1-2 sentences * for what_happened / why_it_matters / what_learned; 1 * sentence for what_action). An empty section is a hard * `MISSING_BRIEF_SECTION` error. * * 2. The build path is lenient on raw prose and strict on the * final shape — `buildEvidenceBrief` calls * `EvidenceBriefSchema.parse(...)` so a partial brief throws * before reaching the database. * * 3. `renderRecommendationPayload` refuses to return a * recommendation envelope unless the brief passes the 4-section * guard. This is the CLI's single source of truth for "may I * show this to the user?". * * 4. The `evaluator_summary` is a separate field on the * crystallization_event row (spec §4.5) and is NOT part of the * brief. It feeds the broader recommendation envelope. * * Out of scope (deferred to later slices): * - LLM-authored brief generation from live trace evidence (M8 dogfood). * - brief rewrite-on-update semantics. */ /** * The minimum viable trace shape that the builder needs to render * a brief. The trace is the EVIDENCE; the builder is format-stable * so a future slice can swap in a richer trace source without * editing every caller. */ export declare const BriefTraceInputSchema: z.ZodObject<{ trace_id: z.ZodString; what_happened: z.ZodString; why_it_matters: z.ZodString; what_learned: z.ZodString; what_action: z.ZodString; bullets: z.ZodDefault>; source_trace_pointers: z.ZodDefault>; }, z.core.$strip>; export type BriefTraceInput = z.input; /** * The summary emitted by the independent evaluators (spec §4.5 * `evaluator_summary` field). Optional for the brief builder — the * brief can be built without it, but a filled evaluator_summary * flows into the recommendation envelope. */ export declare const EvaluatorSummarySchema: z.ZodObject<{ one_liner: z.ZodDefault; risk_tags: z.ZodDefault>; }, z.core.$strip>; export type EvaluatorSummary = z.input; export declare const RecommendationPayloadSchema: z.ZodObject<{ brief: z.ZodObject<{ what_happened: z.ZodString; why_it_matters: z.ZodString; what_learned: z.ZodString; what_action: z.ZodString; }, z.core.$strict>; bullets: z.ZodDefault>; source_trace_pointers: z.ZodDefault>; evaluator_summary: z.ZodDefault; risk_tags: z.ZodDefault>; }, z.core.$strip>>; }, z.core.$strip>; export type RecommendationPayload = z.infer; export declare class BriefSectionError extends Error { readonly code: "MISSING_BRIEF_SECTION"; readonly findings: ReadonlyArray<{ path: string; message: string; }>; constructor(message: string, findings?: ReadonlyArray<{ path: string; message: string; }>); } /** * Build a 4-section EvidenceBrief from a finished trace recap. * * The function is STRICT: it parses the input trace through * `BriefTraceInputSchema`, then parses the assembled brief through * `EvidenceBriefSchema`. Any missing section throws * `BriefSectionError(MISSING_BRIEF_SECTION)` — the same code that * `safeParseEvidenceBrief` returns — so a single error code is the * user-facing signal for "brief incomplete, do not render". * * Brief-section related ZodErrors (e.g. `min(1)` on a section) are * translated to `BriefSectionError` so callers only handle one * shape of failure. Non-section ZodErrors (e.g. invalid `trace_id`) * are re-raised unchanged. * * NOTE: callers who already have raw NL strings can also call * `parseEvidenceBrief` directly; this function is the opinionated * shape for trace -> brief. */ export declare function buildEvidenceBrief(trace: BriefTraceInput, evaluatorSummary?: EvaluatorSummary): EvidenceBrief; /** * Render the user-facing recommendation envelope (brief + bullets + * trace pointers + evaluator summary). The function refuses to * return a payload unless ALL 4 brief sections are present — this * is the single CLI-facing gate per spec §10 RL-7. * * On success, returns the validated `RecommendationPayload`. On a * missing-section brief, throws `BriefSectionError`. */ export declare function renderRecommendationPayload(trace: BriefTraceInput, evaluatorSummary?: EvaluatorSummary): RecommendationPayload; /** * Convenience: validate an arbitrary unknown payload AS IF it were a * recommendation envelope. Returns a Result-like shape so the CLI can * render a structured MISSING_BRIEF_SECTION error without try/catch * noise. */ export declare function safeRenderRecommendationPayload(input: unknown): { ok: true; payload: RecommendationPayload; } | { ok: false; code?: 'MISSING_BRIEF_SECTION'; findings: Array<{ path: string; message: string; }>; };