/** * Budgeting — the deterministic estimation model (pure). Converts a story's * COUNTABLE drivers (spec structure) + the LLM's RELATIVE `effort` block into a * 3-point, dual-currency estimate (human manhours + agent tokens), then rolls a * backlog up to portfolio percentiles via Monte-Carlo simulation. * * Boundary: the LLM sizes relative + names qualitative drivers (it's unreliable at * absolute hours); THIS model owns the absolute conversion via calibrated * coefficients. The seed coefficients below are illustrative defaults — the real * ones are LEARNED from actuals (reference-class forecasting / the SizeCostTable). * See dash docs/BUDGETING-AND-ROADMAP.md. */ import type { Spec, EffortSize } from "@slowcook-ai/core"; /** Countable complexity drivers extracted from the spec structure (the inside view). */ export interface StoryDrivers { entities: number; fields: number; relations: number; endpoints: number; surfaces: number; /** Σ declared states across surfaces (≥1 per surface) — the EPSS matrix size. */ epssCells: number; scenarios: number; invariants: number; fidelityModes: number; openQuestions: number; personas: number; } /** A 3-point estimate (optimistic / most-likely / pessimistic) in one unit. */ export interface ThreePoint { o: number; m: number; p: number; } /** A story's estimate across both currencies, 3-point each. */ export interface StoryEstimate { storyId: string; title: string; epic: string | null; /** human manhours (design + qa + review). */ hours: ThreePoint; /** agent tokens (build + test). */ tokens: ThreePoint; /** total cost in cents (labor + compute). */ costCents: ThreePoint; risk: "low" | "medium" | "high"; confidence: number; drivers: StoryDrivers; qualitativeDrivers: string[]; } /** Calibration — seed coefficients (illustrative; calibrate from actuals). */ export interface Calibration { /** relative weight per t-shirt size. */ weight: Record; /** human hours per design/qa weight unit. */ designHoursPerWeight: number; qaHoursPerWeight: number; /** agent k-tokens per build weight unit. */ buildKTokPerWeight: number; /** structural coefficients (the inside view). */ structural: { designBase: number; dSurf: number; dMode: number; buildBaseK: number; bEntity: number; bField: number; bApi: number; bSurf: number; qaBase: number; qCell: number; qInv: number; testBaseK: number; tScenario: number; reviewBase: number; rSurf: number; rInv: number; }; /** multiplier per qualitative driver (default 1.0 when absent). */ driverMult: Record; /** added band per risk level. */ riskAdd: Record<"low" | "medium" | "high", number>; baseBand: number; /** $/hour (cents) blended labor rate. */ roleRateCents: number; /** $/million-tokens (cents) blended compute rate. */ tokenRateCentsPerM: number; } export declare const SEED_CALIBRATION: Calibration; /** Count the structural drivers from a spec (the inside view). */ export declare function extractDrivers(spec: Spec): StoryDrivers; /** Estimate one story: countable drivers ⊕ the LLM effort block → 3-point dual-currency. */ export declare function estimateStory(spec: Spec, calib?: Calibration): StoryEstimate; /** Sample a triangular(o,m,p) distribution given u∈[0,1). */ export declare function sampleTriangular(tp: ThreePoint, u: number): number; export interface Percentiles { p50: number; p85: number; p95: number; } export interface PortfolioForecast { hours: Percentiles; tokens: Percentiles; costCents: Percentiles; /** the deterministic Σ of most-likely values (the v1 method) for comparison. */ deterministic: { hours: number; tokens: number; costCents: number; }; iterations: number; stories: number; } /** Monte-Carlo: per iteration draw a systemic factor, then sample each story's * 3-point per currency, sum, report percentiles. */ export declare function monteCarloPortfolio(estimates: StoryEstimate[], iterations?: number, seed?: number): PortfolioForecast; //# sourceMappingURL=model.d.ts.map