spb/autoscholar
Public
1import { z } from "zod";23export const GateStatus = z.enum(["pass", "fail", "warn", "skip"]);4export const GateSeverity = z.enum(["hard", "soft"]);56export const GateResult = z.object({7 gate: z.string(),8 severity: GateSeverity,9 status: GateStatus,10 message: z.string(),11 evidence: z.record(z.string(), z.unknown()).default({}),12});13export type GateResult = z.infer<typeof GateResult>;1415export const RubricDimension = z.enum([16 "novelty_relevance",17 "scientific_validity",18 "evidence_traceability",19 "reproducibility_robustness",20 "manuscript_craftsmanship",21 "integrity_disclosure",22]);2324export const RubricScore = z.object({25 dimension: RubricDimension,26 score: z.number().int().min(0).max(5),27 evidence: z.string(),28});2930export const ReviewFinding = z.object({31 id: z.string(),32 severity: z.enum(["blocker", "major", "minor"]),33 category: z.string(),34 title: z.string(),35 detail: z.string(),36 proposedTest: z.string().optional(),37 resolution: z.enum(["open", "resolved", "wontfix"]).default("open"),38 resolutionNote: z.string().optional(),39});4041export const ReviewReport = z.object({42 round: z.number().int().min(1),43 reviewerModel: z.string(),44 summary: z.string(),45 rubric: z.array(RubricScore),46 findings: z.array(ReviewFinding),47 recommendation: z.enum(["accept", "minor_revision", "major_revision", "reject"]),48 limitationsOfThisReview: z.string(),49});50export type ReviewReport = z.infer<typeof ReviewReport>;5152export const QaReport = z.object({53 policyVersion: z.string(),54 mode: z.string(),55 evaluatedAt: z.string(),56 gates: z.array(GateResult),57 publishable: z.boolean(),58 hardFailures: z.array(z.string()),59 warnings: z.array(z.string()),60 synthetic: z.boolean().default(false),61});62export type QaReport = z.infer<typeof QaReport>;63