// A reviewer's decision on a line the platform extracted, as Document Items feedback (ADR-069 d9). // // The line's change carries the item it was read from (`source.itemRef`, `:`); a // decision on any other line is not the platform's to learn from and maps to nothing. What goes back is // the decision and, for an edit or an approval of an edited line, the label and value as the reviewer // left them: organization-scoped feedback the platform keeps with the run, never an audit event. import { type LineChange, lineChangeSchema } from "../contract/index.js" /** The feedback the platform takes for one item (`@conusai-kit/platform` `ItemFeedback`, declared here so core imports no SDK). */ export interface ItemFeedback { readonly item_id: string readonly decision: "approved" | "edited" | "rejected" readonly fields?: Readonly> } export interface ItemRef { readonly runId: number readonly itemId: string } /** The platform item a line was read from, or undefined for a line the platform did not extract. */ export function itemRefOf(change: unknown): ItemRef | undefined { const parsed = lineChangeSchema.safeParse(change) const ref = parsed.success ? parsed.data.source?.itemRef : undefined const match = ref === undefined ? null : /^(\d+):(.+)$/.exec(ref) if (!match) return undefined return { runId: Number(match[1]), itemId: match[2] as string } } /** One decision as the feedback the platform takes; undefined when the line is not a platform item. */ export function feedbackOf( decision: ItemFeedback["decision"], change: unknown, ): { runId: number; feedback: ItemFeedback } | undefined { const ref = itemRefOf(change) if (!ref) return undefined const line = change as LineChange const corrected = decision === "edited" || (decision === "approved" && line.edited) return { runId: ref.runId, feedback: { item_id: ref.itemId, decision: corrected ? "edited" : decision, ...(corrected ? { fields: { label: line.label, value: line.value } } : {}), }, } }