import { type CandidateVerificationStatus, type SupportAbstainReason, type SupportVerificationMethod, type SupportVerificationResult } from "../candidate-verification.js"; import { type ReviewCandidate, type ReviewItem } from "../review-resource.js"; import type { InterpretationAnswerImpact, InterpretationReadingKind } from "../types.js"; import { type ReviewWorkbenchResult } from "./review-workbench.js"; export interface ReviewPresentationAdapter { readonly labelForTarget?: (target: string, context: ReviewItemPresentationContext) => string | undefined; readonly labelForCandidateRole?: (role: ReviewCandidate["role"] | undefined, context: ReviewCandidatePresentationContext) => string | undefined; readonly summarizeValue?: (value: unknown, context: ReviewValuePresentationContext) => string | undefined; readonly linkForReviewItem?: (item: ReviewItem, context: ReviewItemPresentationContext) => ReviewPresentationLink | undefined; readonly linkForSource?: (sourceRef: string, context: ReviewCandidatePresentationContext) => ReviewPresentationLink | undefined; readonly linkForTraceRef?: (ref: ReviewTraceRef, context: ReviewTracePresentationContext) => ReviewPresentationLink | undefined; readonly statusLabel?: (status: string, context: ReviewItemPresentationContext) => string | undefined; } export interface ReviewItemPresentationContext { readonly item: ReviewItem; } export interface ReviewCandidatePresentationContext extends ReviewItemPresentationContext { readonly candidate: ReviewCandidate; } export interface ReviewValuePresentationContext extends ReviewCandidatePresentationContext { readonly value: unknown; } export interface ReviewTracePresentationContext extends ReviewItemPresentationContext { readonly candidate?: ReviewCandidate; } export interface ReviewPresentationLink { readonly label?: string; readonly href: string; } export interface ReviewTraceRef { readonly label: string; readonly value: string; readonly kind: "review-item" | "candidate" | "candidate-set" | "claim" | "source" | "locator" | "proposal" | "external-record"; readonly link?: ReviewPresentationLink; } export interface ReviewCandidatePresentation { readonly candidate: ReviewCandidate; readonly roleLabel: string; readonly valueLabel: string; readonly valueText: string; readonly sourceLabel: string; readonly sourceText: string; readonly sourceLink?: ReviewPresentationLink; readonly traceRefs: readonly ReviewTraceRef[]; } export interface ReviewItemPresentation { readonly item: ReviewItem; readonly target: string; readonly targetLabel: string; readonly statusLabel: string; readonly reviewItemLink?: ReviewPresentationLink; readonly traceRefs: readonly ReviewTraceRef[]; readonly candidates: readonly ReviewCandidatePresentation[]; /** * Proposals for this claim that an envelope import left out because the * source text at their cited span is not their excerpt. Unverifiable, not * disproven: every decision surface shows them. Empty for other items. */ readonly excludedProposals: readonly ExcludedProposalPresentation[]; /** * Stored `excludedProposals` entries that {@link excludedProposals} cannot * show: malformed entries, or every entry of an item whose envelope binding * is not intact. Hiding a rival is the unsafe direction, so every surface * that shows excluded proposals shows this notice too. Absent when every * stored entry is shown. */ readonly excludedProposalsUnreadable?: ExcludedProposalsUnreadable; /** * For an envelope-imported item, whether its import checked excerpts * against the prepared artifact. Absent for other items, and for an item * whose envelope binding is missing, which cannot claim either. */ readonly excerptVerification?: "verified" | "unverified"; } export interface ExcludedProposalPresentation { readonly proposalIndex: number; readonly value: unknown; readonly valueText: string; readonly locator: string; readonly excerpt: string; } export interface ExcludedProposalsUnreadable { /** * `malformed-entries`: some stored entries are not well-formed. * `binding-broken`: the item's extraction binding is not intact, so none of * its stored entries can be vouched for. */ readonly reason: "malformed-entries" | "binding-broken"; /** How many stored entries are not shown; absent when the stored field is not a list. */ readonly count?: number; } export interface ReviewResultPresentation { readonly result: ReviewWorkbenchResult; readonly item?: ReviewItem; readonly target: string; readonly targetLabel: string; readonly decisionLabel: string; /** Absent when the decision selects no candidate (reject-all or could-not-confirm on a conflict). */ readonly selectedValueText?: string; readonly applyMeaning: string; readonly reviewItemLink?: ReviewPresentationLink; readonly traceRefs: readonly ReviewTraceRef[]; } /** * Structural input for {@link buildInterpretationReadingPresentation}: either * a Survey `Interpretation` record (`id`) or the entry Survey projects onto a * claim at `metadata.survey.interpretations[]` (`interpretationId`). Kind and * impact arrive as plain strings when read back from projected metadata. */ export interface InterpretationReadingSource { readonly id?: string; readonly interpretationId?: string; readonly readingKind?: string; readonly answerImpact?: string; readonly ruleLocator: string; readonly reading: string; readonly actor: string; readonly recordedAt: string; } export interface InterpretationReadingPresentation { readonly interpretationId: string; readonly readingKind: InterpretationReadingKind; readonly kindLabel: string; readonly answerImpact?: InterpretationAnswerImpact; readonly answerImpactLabel?: string; readonly reading: string; readonly actor: string; readonly recordedAt: string; readonly ruleLocator: string; /** * Always `"authored-judgment"`. This is DERIVED from the record type, not a * stored flag: every Interpretation reading is a producer-authored reading * by contract (CONTEXT.md "Interpretation Record"), never a machine-observed * fact. Renderers must present readings under this marking, visually * distinct from machine-observed values — the StatementBadge / ADR 0003 §4 * discipline (blending the two is the defect class of #247). */ readonly provenance: "authored-judgment"; readonly provenanceLabel: string; } /** * Presents one interpretation reading as authored judgment. Fails closed on * unknown reading-kind / answer-impact vocabulary rather than rendering an * authored record under a label nothing derived. */ export declare function buildInterpretationReadingPresentation(source: InterpretationReadingSource): InterpretationReadingPresentation; /** * One sentence naming every excluded proposal, for surfaces that speak in * text (the MCP item, the recorded decision prompt). Undefined when none. */ export declare function excludedProposalsSentence(excluded: readonly ExcludedProposalPresentation[]): string | undefined; /** * One sentence saying that stored excluded proposals cannot be shown, for * every surface that shows excluded proposals. Undefined when none are hidden. */ export declare function excludedProposalsUnreadableSentence(unreadable: ExcludedProposalsUnreadable | undefined): string | undefined; export interface CandidateVerificationRecordPresentation { readonly recordId: string; readonly verifierId: string; readonly verifierVersion: string; readonly method: SupportVerificationMethod; readonly result: SupportVerificationResult; readonly abstainReason?: SupportAbstainReason; readonly createdAt: string; } /** * What the verifier records on one candidate say about the value under * review. Only candidates that carry `verifications` get a note, so a * candidate no verifier looked at shows nothing rather than a verdict. */ export interface CandidateVerificationNote { /** Position in `item.spec.candidates`; ids are not assumed unique. */ readonly candidateIndex: number; readonly candidateId: string; readonly subjectLabel: string; /** As {@link foldCandidateVerifications}: `not-evaluated`, `abstained` (only abstentions apply) or `evaluated`. */ readonly status: CandidateVerificationStatus; readonly records: readonly CandidateVerificationRecordPresentation[]; /** Valid records bound to another value, candidate or input. */ readonly inapplicableCount: number; /** Records that failed validation (edited, inconsistent or malformed); never shown as verdicts. */ readonly rejectedCount: number; readonly sentence: string; } /** * Verifier notes for every candidate that carries records, read against the * value each surface is deciding on: the candidate's own value, or the * reviewer's edit when an accept carries one (records on the proposed value do * not apply to an edited value). Records are validated here, so an inconsistent * record is counted and ignored on every surface alike. */ export declare function candidateVerificationNotes(item: ReviewItem, editedValue?: unknown): CandidateVerificationNote[]; export declare function buildReviewItemPresentation(item: ReviewItem, adapter?: ReviewPresentationAdapter): ReviewItemPresentation; export declare function buildReviewCandidatePresentation(item: ReviewItem, candidate: ReviewCandidate, adapter?: ReviewPresentationAdapter, targetLabel?: string): ReviewCandidatePresentation; export declare function buildReviewResultPresentation(result: ReviewWorkbenchResult, item: ReviewItem | undefined, adapter?: ReviewPresentationAdapter): ReviewResultPresentation; export declare function humanizeIdentifier(value: string): string;