# Financial Model **Location**: `src/yc_bench/db/models/ledger.py`, `src/yc_bench/cli/finance_commands.py`, `src/yc_bench/cli/report_commands.py`, `src/yc_bench/core/handlers/` ## Overview The financial model simulates a startup's cash flow: revenue from completed tasks, costs from employee payroll, and penalties for failures. Running out of money triggers bankruptcy and ends the simulation. ## Design Choices ### Cents-Based Integer Arithmetic All financial values are stored as `BigInteger` in cents: ``` $1,000.00 = 100_000 cents ``` **Why cents?** Floating-point arithmetic introduces rounding errors that compound over hundreds of transactions. Integer cents guarantee exact financial accounting -- critical for a deterministic benchmark. ### Immutable Append-Only Ledger Every financial transaction creates a `LedgerEntry` that is never modified or deleted: ```python class LedgerEntry: category: MONTHLY_PAYROLL | TASK_REWARD | TASK_FAIL_PENALTY | TASK_CANCEL_PENALTY amount_cents: int # negative for costs, positive for revenue occurred_at: datetime ref_type: str # optional reference to source entity ref_id: UUID # optional reference ID ``` **Why immutable?** An append-only ledger provides: - Complete audit trail for debugging - Ability to reconstruct balance at any point in time - No risk of silent data corruption - Natural fit for the `finance ledger` and `report monthly` CLI commands ## Revenue Sources ### Task Rewards On successful (on-time) completion: ``` reward = base_reward × (1 + prestige_scale × (avg_prestige - 1)) ``` Where `avg_prestige` is averaged across the task's required domains. Higher prestige = higher payouts. **Design choice**: Prestige-scaled rewards create a positive feedback loop that mirrors real business dynamics -- reputation leads to better opportunities. ### Revenue Timing Rewards are credited immediately upon task completion (when the `task_completed` event fires with `success=True`). ## Cost Sources ### Monthly Payroll Payroll is deducted on the **first business day** of each month: ``` total_payroll = sum(employee.salary_cents for all employees) ``` **Design choice**: Monthly payroll creates predictable but unavoidable costs. The agent must maintain positive cash flow to cover it. ### Salary Bumps Each completed task increases salaries by a fixed per-tier amount (linear, not compounding): ``` tier_midpoints = {junior: (min+max)/2, mid: (min+max)/2, senior: (min+max)/2} for each assigned employee: bump = tier_midpoints[employee.tier] * salary_bump_pct salary_cents += bump # fixed amount per task ``` **Design choice**: Linear salary bumps create steady payroll growth without exponential compounding. A junior gets ~$30/task bump, mid ~$70, senior ~$125 (at 1% of tier midpoint). This avoids runaway payroll in the late game while still creating pressure. ### Failure Penalties Late task completion incurs no direct financial penalty beyond the missed reward opportunity. However, the prestige loss from failure reduces future reward scaling. ### Cancel Penalties Cancellation may incur a financial penalty depending on configuration (some presets charge a fraction of the reward). ## Payroll-Event Tie-Breaking When payroll and events fall on the same timestamp: ``` Payroll is processed BEFORE events ``` **Design choice**: This ordering is critical. If a task completes on the same day as payroll: 1. Payroll deducts first (may push funds negative) 2. Task completion reward credits (may save from bankruptcy) 3. Bankruptcy check happens after both This gives the agent the benefit of the doubt -- a task completing on payday can save the company. ## Bankruptcy Bankruptcy triggers when `funds_cents < 0` after payroll processing: ```python if company.funds_cents < 0: insert_bankruptcy_event(session, company_id, sim_time) ``` **Design choice**: Bankruptcy is checked only after payroll (not after penalties). This simplifies the model and makes payroll the primary survival constraint. ### Bankruptcy as Terminal State Once bankruptcy fires, the simulation ends. There is no recovery mechanic. **Why no bailout?** The benchmark tests whether the agent can sustainably manage a business. Allowing recovery would dilute this signal. ## Financial Reports ### Ledger Query (`finance ledger`) The agent can query the full transaction history with filters: - Category filter - Date range filter - Pagination ### Monthly P&L (`report monthly`) Aggregates transactions by month: ``` Month Revenue Payroll Penalties Net 2025-01 $50,000 $30,000 $0 $20,000 2025-02 $35,000 $30,300 $5,000 -$300 ``` **Design choice**: Structured financial reporting gives the agent the data it needs to make informed decisions about task selection and resource allocation. ## Runway Calculation The `company status` command includes a runway estimate: ``` runway_months = funds_cents / monthly_payroll_cents ``` This helps the agent gauge urgency. Low runway signals that the agent needs profitable tasks quickly. ## Difficulty Scaling Financial pressure scales with difficulty preset: | Preset | Initial Funds | Payroll Pressure | Penalties | |--------|--------------|-----------------|-----------| | tutorial | Very high | Low | Minimal | | easy | High | Moderate | Low | | medium | Moderate | Moderate | Standard | | hard | Low | High | 1.5x | | nightmare | Very low | Very high | 2x |