export type RiskLevel = "low" | "medium" | "high" | "critical"; export type UserAuthorization = "unknown" | "low" | "medium" | "high"; export type ReviewOutcome = "allow" | "deny"; export interface Assessment { outcome: ReviewOutcome; riskLevel: RiskLevel; userAuthorization: UserAuthorization; rationale: string; } const RISKS = new Set(["low", "medium", "high", "critical"]); const AUTHORIZATIONS = new Set(["unknown", "low", "medium", "high"]); function isRecord(value: unknown): value is Record { return typeof value === "object" && value !== null && !Array.isArray(value); } function parseObject(text: string): unknown { try { return JSON.parse(text) as unknown; } catch { const first = text.indexOf("{"); const last = text.lastIndexOf("}"); if (first < 0 || last <= first) throw new Error("Reviewer output did not contain a JSON object"); return JSON.parse(text.slice(first, last + 1)) as unknown; } } function concise(text: string): string { const normalized = text.replace(/\s+/gu, " ").trim(); return Array.from(normalized).slice(0, 500).join(""); } export function parseAssessment(text: string): Assessment { const value = parseObject(text); if (!isRecord(value)) throw new Error("Reviewer output must be a JSON object"); const outcome = value["outcome"]; if (outcome !== "allow" && outcome !== "deny") throw new Error("Reviewer output requires outcome allow or deny"); const rawRisk = value["risk_level"]; if (rawRisk !== undefined && (typeof rawRisk !== "string" || !RISKS.has(rawRisk as RiskLevel))) { throw new Error("Reviewer risk_level is invalid"); } const rawAuthorization = value["user_authorization"]; if ( rawAuthorization !== undefined && (typeof rawAuthorization !== "string" || !AUTHORIZATIONS.has(rawAuthorization as UserAuthorization)) ) { throw new Error("Reviewer user_authorization is invalid"); } const rawRationale = value["rationale"]; if (rawRationale !== undefined && typeof rawRationale !== "string") { throw new Error("Reviewer rationale is invalid"); } const riskLevel = rawRisk === undefined ? (outcome === "allow" ? "low" : "high") : (rawRisk as RiskLevel); const userAuthorization = rawAuthorization === undefined ? "unknown" : (rawAuthorization as UserAuthorization); const suppliedRationale = rawRationale === undefined ? "" : concise(rawRationale); const rationale = suppliedRationale.length > 0 ? suppliedRationale : outcome === "allow" ? "The supplied evidence supports this action." : "The supplied evidence does not safely authorize this action."; return { outcome, riskLevel, userAuthorization, rationale }; }