// Shared types for the claim-auditor. Every field exists for a reason; // if something can't be verified from a check, it goes into `evidence` // so the verdict is inspectable, not a black box. export type CheckKind = "static" | "dynamic" | "inference" | "kb_query"; export type Severity = "info" | "warn" | "block"; export interface Claim { // Verbatim phrase that raised the claim — e.g. "Phase 38 shipped", // "verified end-to-end", "works after restart". Used as the "what // does the author assert" input to downstream checks. text: string; // Where it came from. `commit_sha` is the short hash; `location` // is a file:line for in-diff claims, or "pr_body" / "commit_message". commit_sha: string; location: string; // Heuristic rating of how strong the claim is. "green+tested" // is strong; "should work" is weak. Drives sensitivity — stronger // claims get harder-blocked on weak evidence. // // "empirical" is a separate class: runtime measurements like // "N cloud calls" / "306s end-to-end" / "accepted on attempt N". // These cannot be verified from a static diff — only from the test // output that produced them. Inference skips diff-verification for // empirical claims; they become info-level context unless a future // runtime_evidence check contradicts them. strength: "weak" | "moderate" | "strong" | "empirical"; } export interface Finding { check: CheckKind; severity: Severity; claim_text?: string; // Free-form short description: "field added but never read", "no // test covers this code path", "cloud model says placeholder". summary: string; // Concrete evidence: file paths, line numbers, log excerpts, test // output, cloud-model verdict. No handwaving. evidence: string[]; } export interface Verdict { pr_number: number; head_sha: string; audited_at: string; overall: "approve" | "request_changes" | "block"; findings: Finding[]; // Real numbers that downstream policy can gate on. e.g. if the // hybrid test produced latency numbers or token counts, they // surface here so /auditor/history is queryable. metrics: Record; // Short one-line justification for the `overall` verdict. What // gets posted as the commit-status description in Gitea (max 140 // chars) must fit here. one_liner: string; } export interface PrSnapshot { number: number; head_sha: string; base_sha: string; title: string; body: string; state: "open" | "closed" | "merged"; author: string; // Array of commit messages in the PR (not diffs — those are // fetched on-demand per-check). commits: Array<{ sha: string; message: string; author: string }>; // File paths touched by the PR, with lines-added / lines-removed. files: Array<{ path: string; additions: number; deletions: number }>; }