SPB Git

spb/autoscholar

Public
2.6 KB · 59 lines typescript
1import { type ArtifactDescriptor, CONTRACT_PATHS, type ResearchMode } from "@autoscholar/schemas";2import { MODE_PROFILES } from "./profiles.js";34export interface ContractCheck {5  mode: ResearchMode;6  missing: string[];7  present: string[];8  ok: boolean;9}1011/** Deterministic check that the artifact set contains every mode-required path. */12export function checkArtifactContract(13  mode: ResearchMode,14  artifacts: Pick<ArtifactDescriptor, "path">[],15): ContractCheck {16  const paths = new Set(artifacts.map((a) => a.path));17  const required = MODE_PROFILES[mode].requiredArtifacts;18  const missing = required.filter((p) => !paths.has(p));19  const present = required.filter((p) => paths.has(p));20  return { mode, missing, present, ok: missing.length === 0 };21}2223/** Artifacts that are promoted to the public bundle at publication (private provenance is redacted separately). */24export const PUBLIC_PROMOTION_RULES: Array<{ match: RegExp; kind: string; contentType?: string }> = [25  { match: /^manuscript\/main\.pdf$/, kind: "pdf", contentType: "application/pdf" },26  { match: /^manuscript\/(main\.tex|references\.bib|.*\.(tex|bib|cls|sty|bst))$/, kind: "manuscript" },27  { match: /^manuscript\/abstract\.md$/, kind: "manuscript" },28  { match: /^manuscript\/metadata\.json$/, kind: "manuscript" },29  { match: /^results\/figures\/.*\.(pdf|png|svg)$/, kind: "figure" },30  { match: /^results\/tables\/.*\.(tex|csv|md)$/, kind: "table" },31  { match: /^results\/(metrics\.json|robustness\.md)$/, kind: "result" },32  { match: /^code\/(?!.*\.(env|pem|key)$).*/, kind: "code" },33  { match: /^data\/(README\.md|manifest\.json)$/, kind: "data" },34  { match: /^data\/.*\.(csv|parquet|json|txt|zip)$/, kind: "data" },35  { match: /^sources\/(references\.bib|sources\.json|source-map\.json)$/, kind: "source" },36  { match: /^review\/(review-1\.md|revisions\.md|qa-report\.json)$/, kind: "review" },37  { match: /^plan\/(research-plan\.md|feasibility\.json)$/, kind: "plan" },38  { match: /^provenance\/(run-summary\.json|checksums\.sha256)$/, kind: "provenance" },39];4041/** Paths that are never promoted (private). */42export const NEVER_PUBLIC = [43  /^input\//,44  /^provenance\/events\.jsonl$/,45  /\.env($|\.)/,46  /(^|\/)\.(ssh|aws|claude)(\/|$)/,47  /\.(pem|key|p12)$/,48  /^logs?\//,49];5051export function isPromotable(path: string): { promote: boolean; kind?: string; contentType?: string } {52  if (NEVER_PUBLIC.some((r) => r.test(path))) return { promote: false };53  for (const r of PUBLIC_PROMOTION_RULES)54    if (r.match.test(path)) return { promote: true, kind: r.kind, contentType: r.contentType };55  return { promote: false };56}5758export { CONTRACT_PATHS };59
Files · main
Menu

Theme