SPB Git

spb/autoscholar

Public
4.7 KB · 130 lines typescript
1import { z } from "zod";2import { Discipline, ResearchMode } from "./modes.js";34export const RunStatus = z.enum([5  "draft",6  "validated",7  "queued",8  "provisioning",9  "running",10  "quality_check",11  "quality_failed",12  "revising",13  "ready_to_publish",14  "awaiting_approval",15  "publishing",16  "published",17  "cancelling",18  "cancelled",19  "failed",20  "retrying",21]);22export type RunStatus = z.infer<typeof RunStatus>;2324/** Valid transitions of the run state machine (enforced server-side, appended to the event ledger). */25export const RUN_TRANSITIONS: Record<RunStatus, readonly RunStatus[]> = {26  draft: ["validated", "cancelled"],27  validated: ["queued", "cancelled"],28  queued: ["provisioning", "cancelling", "cancelled", "failed"],29  provisioning: ["running", "quality_check", "retrying", "cancelling", "cancelled", "failed"],30  running: ["quality_check", "retrying", "cancelling", "failed", "revising"],31  quality_check: ["quality_failed", "ready_to_publish", "cancelling", "failed"],32  quality_failed: ["revising", "cancelled", "failed", "ready_to_publish"],33  revising: ["queued", "retrying", "cancelling", "failed"],34  ready_to_publish: ["awaiting_approval", "publishing", "cancelled", "failed"],35  awaiting_approval: ["publishing", "cancelled", "quality_failed"],36  publishing: ["published", "failed", "ready_to_publish"],37  published: [],38  cancelling: ["cancelled", "failed"],39  cancelled: [],40  failed: ["retrying", "queued"],41  retrying: ["queued", "failed", "cancelled"],42};4344export const ACTIVE_RUN_STATUSES: readonly RunStatus[] = [45  "queued",46  "provisioning",47  "running",48  "quality_check",49  "revising",50  "retrying",51  "publishing",52];5354export const TERMINAL_RUN_STATUSES: readonly RunStatus[] = ["published", "cancelled", "failed"];5556export const STAGES = [57  { index: 0, key: "preflight", name: "Preflight" },58  { index: 1, key: "framing", name: "Research framing" },59  { index: 2, key: "literature", name: "Literature and prior art" },60  { index: 3, key: "design", name: "Research design and foundations" },61  { index: 4, key: "execute", name: "Execute research" },62  { index: 5, key: "robustness", name: "Robustness and falsification" },63  { index: 6, key: "manuscript", name: "Manuscript construction" },64  { index: 7, key: "review", name: "Independent critical review" },65  { index: 8, key: "reproduction", name: "Reproduction and build" },66  { index: 9, key: "quality", name: "Quality decision" },67  { index: 10, key: "publication", name: "Publication" },68] as const;69export type StageKey = (typeof STAGES)[number]["key"];70export const StageKey = z.enum(STAGES.map((s) => s.key) as [StageKey, ...StageKey[]]);71export const WORKER_STAGES: readonly StageKey[] = STAGES.slice(0, 9).map((s) => s.key);7273export const StageStatus = z.enum(["pending", "running", "completed", "failed", "skipped", "cancelled"]);74export type StageStatus = z.infer<typeof StageStatus>;7576export const ComputeProfile = z.enum(["standard", "compute-heavy", "memory-heavy"]);77export type ComputeProfile = z.infer<typeof ComputeProfile>;7879/** Immutable job manifest. Server-authored, never contains secrets. */80export const RunManifest = z.object({81  schemaVersion: z.literal(1),82  runId: z.string().uuid(),83  projectId: z.string().uuid(),84  instructionVersionId: z.string().uuid(),85  instructionVersion: z.number().int().positive(),86  instructionSha256: z.string().regex(/^[a-f0-9]{64}$/),87  researchMode: ResearchMode,88  secondaryModes: z.array(ResearchMode).default([]),89  discipline: Discipline,90  computeProfile: ComputeProfile,91  provider: z.literal("anthropic"),92  model: z.string().min(1),93  reviewerModel: z.string().min(1),94  maxBudgetUsd: z.number().positive().max(2000),95  maxRuntimeMinutes: z96    .number()97    .int()98    .positive()99    .max(24 * 60),100  maxAttempts: z.number().int().min(1).max(5),101  autoPublish: z.boolean(),102  qualityPolicyVersion: z.string(),103  createdAt: z.string().datetime(),104  createdBy: z.string().uuid(),105  title: z.string().min(3).max(300),106});107export type RunManifest = z.infer<typeof RunManifest>;108109export const LaunchRunRequest = z.object({110  projectId: z.string().uuid(),111  instructionVersionId: z.string().uuid(),112  idempotencyKey: z.string().min(8).max(128),113  title: z.string().min(3).max(300),114  researchMode: ResearchMode,115  secondaryModes: z.array(ResearchMode).max(3).default([]),116  discipline: Discipline,117  computeProfile: ComputeProfile.default("standard"),118  model: z.string().min(1).optional(),119  maxBudgetUsd: z.number().positive().max(2000).optional(),120  maxRuntimeMinutes: z121    .number()122    .int()123    .positive()124    .max(24 * 60)125    .optional(),126  maxAttempts: z.number().int().min(1).max(5).default(2),127  autoPublish: z.boolean().default(false),128});129export type LaunchRunRequest = z.infer<typeof LaunchRunRequest>;130
Files · 4ee0eb55785162e74bf5de92a13ac2a30a1c4528
Menu

Theme