# Findings → estimate mapping (effort-based) `estimate.py` builds the 견적 from `sow_templates.yaml` priced via `rate_card.yaml`: **cost = role_rate × billing_rate (0.70) × standard_hours**, grouped by module; 제안가 = 합계 floored to `rounding_unit`. This mirrors OurDigital/D.intelligence's real SOW-based quoting. ## Baseline selection (basic vs treatment) - `treatment` if any finding `severity == critical` **OR** `entity.properties_total > 3` - else `basic` - override with `--baseline`. ## Module inclusion Each baseline carries the standard module set (P&M · Technical SEO · On-page SEO · SEO Growth), matching real quotes. Findings justify modules via the `trigger` field in `sow_templates.yaml`: | Module | trigger finding classes | |---|---| | Planning & Management | always | | Technical SEO | crawlability, cwv, schema_entity | | On-page SEO | onpage, schema_entity | | SEO Growth | measurement, always | ## Hours scaling (portfolio) Tasks marked `scale: true` (Technical SEO + On-page SEO) have their **hours** multiplied sub-linearly by `entity.properties_total` per `rate_card.scaling.bands`. P&M and SEO Growth stay fixed (management/KPI overhead is ~flat). A single-property prospect → ×1.0, which reproduces the real single-site quotes exactly. ## Tools & terms `tools` (e.g. SEMrush Guru) are listed separately — client-subscribed, with +15% procurement markup if billed through us. VAT 별도 · 유효기간 14d · 현금 · 절사 from `rate_card.terms`. ## Validated reproduction (2026-05-28) - `treatment` ×1.0 → 합계 25,340,000 → 제안가 **25,000,000** (real Treatment quote) - `basic` ×1.0 → 합계 10,612,000 → 제안가 **10,500,000** (real Basic quote) Edit `rate_card.yaml` and `sow_templates.yaml` together when rates or standard hours change.