import type { FallbackReviewIndex, FlaggedFileRecord, ShellActivityRecord } from "./types"; export const EMPTY_HANDOFF = "no fallback changes are pending"; const GROUND_TRUTH_LINES = [ " ground truth: inspect the current working-tree diff (git status / git diff) —", " shell mutations are not attributable per file; the diff is authoritative.", ] as const; export function pendingReviewCount(index: Pick): number { return index.reviewed ? 0 : index.flaggedFiles.length; } // OD-11 / DC-4: record always, render as a suffix on the flagged-file line — no separate section, no // reordering, no second handoff format. Gated on `=== 2` so a tier-1 record and a record written before // the field existed both render byte-for-byte as they always did. Shell records get nothing (NG-9/AC-20). const tierSuffix = (file: FlaggedFileRecord): string => file.tier === 2 ? " (tier 2 assistant)" : ""; function renderFlaggedFiles(files: readonly FlaggedFileRecord[]): string[] { return [ " flagged files:", ...files.map((file, position) => ` ${position + 1}. ${file.path} ← ${file.model}${tierSuffix(file)} ${file.timestamp}`), ]; } function renderShellActivity(activity: readonly ShellActivityRecord[]): string[] { return [ " shell activity (UNATTRIBUTED — no file-level attribution claimed):", ...activity.map((record) => ` - ${JSON.stringify(record.command)} (tool-call ${record.toolCallId})`), ]; } export function renderHandoff(index: FallbackReviewIndex): string { if (index.reviewed || (index.flaggedFiles.length === 0 && index.shellActivity.length === 0)) return EMPTY_HANDOFF; const lines = [ `fallback review — episode ${index.episodeId}`, ` root primary : ${index.primary}`, ` status : ${index.status} pending changes: ${pendingReviewCount(index)}`, ]; if (index.flaggedFiles.length > 0) lines.push(...renderFlaggedFiles(index.flaggedFiles)); if (index.shellActivity.length > 0) lines.push(...renderShellActivity(index.shellActivity)); lines.push(...GROUND_TRUTH_LINES); return lines.join("\n"); }