/** * Deterministic expense-variance calculation for the Orisdale worked example. * * Scope: a synthetic demonstration. The rules come from * `finance-variance-contract-v1.json`; they are demonstration rules, not a * customer-approved policy. This file has no imports so that the exact bytes * published on the website are the bytes that were executed and hashed. * * Amounts are held as integer cents. Percentage thresholds are compared with * exact integer cross-multiplication, never with floating-point division. */ export type VarianceCategory = "Material" | "Management attention" | "Within tolerance" | "Needs human review"; export type VarianceDirection = "over budget" | "under budget" | "on budget"; export interface VarianceContract { contractId: string; version: string; scope: { period: string; currency: string }; thresholds: { material: { absoluteCents: number; percent: number }; managementAttention: { absoluteCents: number; percent: number }; }; percentage: { scale: number }; } export interface CsvRecord { [column: string]: string; } export interface Rejection { file: "budget" | "actuals"; rowNumber: number; departmentId: string; reasonCode: | "duplicate_grain" | "missing_required_field" | "invalid_amount" | "unsupported_currency" | "period_out_of_scope" | "missing_budget_row" | "missing_actual_row"; detail: string; } export interface VarianceResult { departmentId: string; departmentLabel: string; period: string; currency: string; budgetCents: number; actualCents: number; varianceCents: number; /** Percentage scaled by 10^scale (4 decimals => 150000 means 15.0000%). Null when unavailable. */ variancePercentScaled: number | null; direction: VarianceDirection; category: VarianceCategory; reviewRequired: boolean; reviewReason: string | null; contractVersion: string; } export interface VarianceRun { results: VarianceResult[]; rejections: Rejection[]; } /** Parses simple comma-separated text. Quoted fields are not part of this example's inputs. */ export function parseCsv(text: string): CsvRecord[] { const lines = text .replace(/^\uFEFF/, "") .split(/\r?\n/) .filter((line) => line.trim() !== ""); if (lines.length === 0) return []; const header = lines[0].split(",").map((cell) => cell.trim()); return lines.slice(1).map((line) => { const cells = line.split(","); const record: CsvRecord = {}; header.forEach((column, index) => { record[column] = (cells[index] ?? "").trim(); }); return record; }); } const AMOUNT_PATTERN = /^\d+(\.\d{1,2})?$/; /** Converts "115000.00" to 11500000 cents. Returns null for anything that is not a non-negative amount with at most two decimals. */ export function parseAmountToCents(value: string): number | null { if (!AMOUNT_PATTERN.test(value)) return null; const [whole, fraction = ""] = value.split("."); const cents = Number(whole) * 100 + Number(fraction.padEnd(2, "0")); return Number.isSafeInteger(cents) ? cents : null; } /** Plain decimal text with two places and no digit grouping, safe for CSV and JSON. */ export function formatCents(cents: number): string { const sign = cents < 0 ? "-" : ""; const absolute = Math.abs(cents); const whole = Math.trunc(absolute / 100).toString(); const fraction = (absolute % 100).toString().padStart(2, "0"); return `${sign}${whole}.${fraction}`; } /** Same value with comma digit grouping, for narrative text only. */ export function formatCentsGrouped(cents: number): string { const plain = formatCents(cents); const [whole, fraction] = plain.split("."); const grouped = whole.replace(/\B(?=(\d{3})+(?!\d))/g, ","); return `${grouped}.${fraction}`; } /** Rounds numerator/denominator half away from zero using BigInt arithmetic. Denominator must be positive. */ function divideRoundHalfAwayFromZero(numerator: bigint, denominator: bigint): bigint { const negative = numerator < BigInt(0); const magnitude = negative ? -numerator : numerator; const quotient = magnitude / denominator; const remainder = magnitude % denominator; const rounded = remainder * BigInt(2) >= denominator ? quotient + BigInt(1) : quotient; return negative ? -rounded : rounded; } export function formatPercentScaled(scaled: number, scale: number): string { const sign = scaled < 0 ? "-" : ""; const absolute = Math.abs(scaled); const divisor = 10 ** scale; const whole = Math.trunc(absolute / divisor); const fraction = (absolute % divisor).toString().padStart(scale, "0"); return `${sign}${whole}.${fraction}`; } function meetsThreshold( absoluteVarianceCents: number, budgetCents: number, threshold: { absoluteCents: number; percent: number }, ): boolean { if (absoluteVarianceCents >= threshold.absoluteCents) return true; // |variance| / budget * 100 >= percent <=> |variance| * 100 >= percent * budget (budget > 0) return ( BigInt(absoluteVarianceCents) * BigInt(100) >= BigInt(threshold.percent) * BigInt(budgetCents) ); } interface ValidRow { rowNumber: number; departmentId: string; label: string; cents: number; } function validateRows( file: "budget" | "actuals", rows: CsvRecord[], amountColumn: string, contract: VarianceContract, rejections: Rejection[], ): Map { const grainCounts = new Map(); rows.forEach((row) => { const key = `${row.department_id}|${row.period}|${row.currency}`; grainCounts.set(key, (grainCounts.get(key) ?? 0) + 1); }); const accepted = new Map(); rows.forEach((row, index) => { const rowNumber = index + 2; // header is row 1 const departmentId = row.department_id ?? ""; const reject = (reasonCode: Rejection["reasonCode"], detail: string) => { rejections.push({ file, rowNumber, departmentId, reasonCode, detail }); }; if (departmentId === "" || (row.period ?? "") === "" || (row.currency ?? "") === "") { reject("missing_required_field", "department_id, period, and currency are required."); return; } if (row.currency !== contract.scope.currency) { reject("unsupported_currency", `Only ${contract.scope.currency} is in scope.`); return; } if (row.period !== contract.scope.period) { reject("period_out_of_scope", `Only period ${contract.scope.period} is in scope.`); return; } const grainKey = `${departmentId}|${row.period}|${row.currency}`; if ((grainCounts.get(grainKey) ?? 0) > 1) { reject( "duplicate_grain", "More than one row exists for this department, period, and currency.", ); return; } const raw = row[amountColumn] ?? ""; if (raw === "") { reject("missing_required_field", `${amountColumn} is empty. It is not treated as zero.`); return; } const cents = parseAmountToCents(raw); if (cents === null) { reject( "invalid_amount", `${amountColumn} must be a non-negative amount with at most two decimals.`, ); return; } accepted.set(departmentId, { rowNumber, departmentId, label: row.department_label ?? departmentId, cents, }); }); return accepted; } export function calculateVariance( budgetRows: CsvRecord[], actualRows: CsvRecord[], contract: VarianceContract, ): VarianceRun { const rejections: Rejection[] = []; const budgets = validateRows("budget", budgetRows, "budget_amount", contract, rejections); const actuals = validateRows("actuals", actualRows, "actual_expense", contract, rejections); const rejectedIds = new Set(rejections.map((rejection) => rejection.departmentId)); const results: VarianceResult[] = []; const departmentIds = Array.from(new Set([...budgets.keys(), ...actuals.keys()])); for (const departmentId of departmentIds) { if (rejectedIds.has(departmentId)) continue; const budget = budgets.get(departmentId); const actual = actuals.get(departmentId); if (!budget) { rejections.push({ file: "budget", rowNumber: 0, departmentId, reasonCode: "missing_budget_row", detail: "An actual row exists without an approved budget row.", }); continue; } if (!actual) { rejections.push({ file: "actuals", rowNumber: 0, departmentId, reasonCode: "missing_actual_row", detail: "An approved budget row exists without an actual row.", }); continue; } const varianceCents = actual.cents - budget.cents; const absoluteVariance = Math.abs(varianceCents); const direction: VarianceDirection = varianceCents > 0 ? "over budget" : varianceCents < 0 ? "under budget" : "on budget"; let variancePercentScaled: number | null = null; let category: VarianceCategory; let reviewRequired = false; let reviewReason: string | null = null; if (budget.cents === 0) { category = "Needs human review"; reviewRequired = true; reviewReason = "Approved budget is zero, so the variance percentage is unavailable."; } else { const scale = BigInt(10 ** contract.percentage.scale); variancePercentScaled = Number( divideRoundHalfAwayFromZero( BigInt(varianceCents) * BigInt(100) * scale, BigInt(budget.cents), ), ); if (meetsThreshold(absoluteVariance, budget.cents, contract.thresholds.material)) { category = "Material"; } else if ( meetsThreshold(absoluteVariance, budget.cents, contract.thresholds.managementAttention) ) { category = "Management attention"; } else { category = "Within tolerance"; } } results.push({ departmentId, departmentLabel: budget.label, period: contract.scope.period, currency: contract.scope.currency, budgetCents: budget.cents, actualCents: actual.cents, varianceCents, variancePercentScaled, direction, category, reviewRequired, reviewReason, contractVersion: contract.version, }); } return { results, rejections }; } /** Deterministic template text. It states computed fields only and names no cause. */ export function describeResult(result: VarianceResult, scale: number): string { const sign = result.varianceCents > 0 ? "+" : result.varianceCents < 0 ? "-" : ""; const amount = `${sign}USD ${formatCentsGrouped(Math.abs(result.varianceCents))}`; const percent = result.variancePercentScaled === null ? "a variance percentage that is unavailable because the approved budget is zero" : `${result.variancePercentScaled > 0 ? "+" : result.variancePercentScaled < 0 ? "-" : ""}${formatPercentScaled(Math.abs(result.variancePercentScaled), scale)}%`; return ( `${result.departmentLabel}, ${result.period}: actual expense was USD ${formatCentsGrouped(result.actualCents)} ` + `against an approved budget of USD ${formatCentsGrouped(result.budgetCents)}. ` + `The variance is ${amount} (${result.direction}), or ${percent}. ` + `Category under contract version ${result.contractVersion}: ${result.category}.` + (result.reviewRequired ? ` Human review is required: ${result.reviewReason}` : "") ); } /** * Claim review. The two kinds of claim are reviewed under different rules. * * A numeric claim is compared with a computed field. That comparison is deterministic. * * A causal claim cannot be verified by this file. The checker never reads the meaning of * free text, so it can never report a cause as supported. It reports only how a claim * relates to evidence that the claim explicitly names: * * - No evidence reference: "unsupported: no claim-linked evidence". A record that happens * to share the department and period is not linked to the claim and is ignored. * - A reference that does not resolve, or resolves to a record for another department or * period: "unsupported: evidence reference not usable". * - Every reference resolves to a record for the claim's department and period: * "evidence linked — human verification required". The record is attached so that a * reader can inspect it. Whether it shows the asserted cause is a human decision, and * this file never records one. */ export type ClaimStatus = | "supported by computed field" | "contradicted by computed field" | "unsupported: no computed result" | "unsupported: no claim-linked evidence" | "unsupported: evidence reference not usable" | "evidence linked — human verification required"; export interface NumericClaim { claimId: string; kind: "numeric"; departmentId: string; text: string; field: "varianceCents" | "category"; expected: string | number; } export interface CausalClaim { claimId: string; kind: "causal"; departmentId: string; text: string; /** Identifiers of evidence records the claim explicitly relies on. Absent or empty means none. */ evidenceRefs?: string[]; } export type Claim = NumericClaim | CausalClaim; export interface DriverEvidence { evidenceId: string; departmentId: string; period: string; description: string; } export interface LinkedEvidence { evidenceId: string; departmentId: string; period: string; description: string; } export interface ClaimAssessment { claimId: string; departmentId: string; text: string; kind: Claim["kind"]; status: ClaimStatus; basis: string; /** Evidence the claim names and that resolves for its department and period. Empty unless status is "evidence linked". */ linkedEvidence: LinkedEvidence[]; /** Causal claims are never confirmed by this checker. Numeric claims do not need confirmation. */ humanConfirmation: "not recorded" | "not applicable"; } function assessNumericClaim( claim: NumericClaim, result: VarianceResult | undefined, ): ClaimAssessment { const base: Omit = { claimId: claim.claimId, departmentId: claim.departmentId, text: claim.text, kind: claim.kind, linkedEvidence: [], humanConfirmation: "not applicable", }; if (!result) { return { ...base, status: "unsupported: no computed result", basis: "No computed result exists for this department.", }; } const actual = result[claim.field]; return { ...base, status: actual === claim.expected ? "supported by computed field" : "contradicted by computed field", basis: `Computed ${claim.field} is ${String(actual)}.`, }; } function assessCausalClaim( claim: CausalClaim, result: VarianceResult | undefined, evidence: DriverEvidence[], ): ClaimAssessment { const base: Omit = { claimId: claim.claimId, departmentId: claim.departmentId, text: claim.text, kind: claim.kind, humanConfirmation: "not recorded", }; const refs = claim.evidenceRefs ?? []; if (refs.length === 0) { return { ...base, status: "unsupported: no claim-linked evidence", linkedEvidence: [], basis: "The claim names no evidence record. Records that share its department and period are not linked to it. The computed variance amount does not establish a cause.", }; } const linked: LinkedEvidence[] = []; const problems: string[] = []; for (const ref of refs) { const record = evidence.find((candidate) => candidate.evidenceId === ref); if (!record) { problems.push(`${ref} does not match any evidence record.`); } else if (!result) { problems.push( `${ref} cannot be placed because no computed result exists for this department.`, ); } else if (record.departmentId !== claim.departmentId || record.period !== result.period) { problems.push( `${ref} belongs to ${record.departmentId}, ${record.period}, not ${claim.departmentId}, ${result.period}.`, ); } else { linked.push({ evidenceId: record.evidenceId, departmentId: record.departmentId, period: record.period, description: record.description, }); } } if (problems.length > 0) { return { ...base, status: "unsupported: evidence reference not usable", linkedEvidence: [], basis: `${problems.join(" ")} No evidence is linked to this claim.`, }; } return { ...base, status: "evidence linked — human verification required", linkedEvidence: linked, basis: `Evidence ${linked.map((record) => record.evidenceId).join(", ")} is linked to this claim for the same department and period. The checker did not read it for meaning. A person must decide whether it shows the stated cause, and no confirmation is recorded.`, }; } export function assessClaims( claims: Claim[], results: VarianceResult[], evidence: DriverEvidence[], ): ClaimAssessment[] { return claims.map((claim) => { const result = results.find((candidate) => candidate.departmentId === claim.departmentId); return claim.kind === "numeric" ? assessNumericClaim(claim, result) : assessCausalClaim(claim, result, evidence); }); }