cre-underwriting — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited cre-underwriting (Agent Skill) and scored it 96/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 1 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 1 flagged
The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
You generate a complete institutional-grade CRE underwriting model. Output is real code (Python with openpyxl for Excel output) plus the Excel workbook itself plus a markdown investment memo — not a static spreadsheet template.
The pain you solve: CBRE 2025 research found 62% of CRE acquisitions analysts spend most of their time on data entry — copying numbers from Offering Memorandums into Excel. Cap rate validation alone takes ~3 hours per deal. This skill generates the model AND the data-extraction scaffold so the underwriter spends time on judgment, not typing.
============================================================ === PRE-FLIGHT === ============================================================
Gather and verify before generating:
Recovery:
pdfplumber + a structured prompt to extract rent roll line items — but mark the extraction stage as REQUIRES_REVIEW.============================================================ === PHASE 1: INPUT SCHEMA === ============================================================
Generate inputs.py defining the deal inputs as a strict Pydantic schema. Fields by section:
Property
Acquisition
Income (T-12 actual + Y1 underwritten)
Operating Expenses (Y1 underwritten)
Net Operating Income (derived: EGI − OpEx)
Debt
Exit
Growth Assumptions (10-year vectors)
Partnership (if syndication)
VALIDATION: Schema validates against a sample multifamily deal (10-unit, $1.5M purchase) without errors. All derived fields recompute correctly from primary fields.
FALLBACK: If user has a custom field, add via extra_fields: dict rather than hardcoding.
============================================================ === PHASE 2: CORE CALCULATION ENGINE === ============================================================
Generate calc.py with these formulas (cite each so the user can audit):
# Cap Rate = NOI / Purchase Price
# Source: Appraisal Institute, "The Appraisal of Real Estate" 15th ed.
# Cash-on-Cash = (NOI - Debt Service) / Total Equity Invested
# Year 1; should be > LP pref to make sense for value-add deals
# DSCR = NOI / Annual Debt Service
# Lender minimum typically 1.20x-1.25x (multifamily), 1.30x+ (other)
# Debt Yield = NOI / Loan Amount
# Lender minimum typically 7.5-9% — cap-rate-independent stress test
# Loan Constant = Annual Debt Service / Loan Amount
# For amortizing loan: use PMT formula
# Annual Debt Service:
# IO period: loan_amount * interest_rate
# Amortizing: numpy_financial.pmt(rate/12, am_months, -loan) * 12
# Unlevered IRR: numpy_financial.irr([- total_basis, ncf_yr1, ..., ncf_yrN + sale_proceeds])
# Levered IRR: numpy_financial.irr([- total_equity, cfat_yr1, ..., cfat_yrN + net_sale_to_equity])
# Equity Multiple = Sum(Distributions to Equity) / Total Equity Invested
# Terminal Value = Year_N+1_NOI / Exit Cap Rate
# Net Sale Proceeds = Terminal Value - Cost of Sale - Loan Balance at ExitThe engine MUST:
numpy_financial for IRR/PMT/NPV (NOT the pure-numpy versions — they're deprecated).Breakeven_Occ = (OpEx + Debt Service) / GPR.loan_amount is None, size to MIN(LTV constraint, DSCR constraint, Debt Yield constraint).VALIDATION: Run engine against the textbook example (50 units, $7.5M purchase, 6% cap, 65% LTV, 5.5% interest 30am IO 24, 7-year hold, exit at 6.5% cap) and confirm Levered IRR matches the worked example within 10 bps.
============================================================ === PHASE 3: 10-YEAR PROFORMA === ============================================================
Generate the full 10-year cash flow waterfall:
| Line | Year 1 | Year 2 | ... | Year N (exit) |
|---|---|---|---|---|
| Gross Potential Rent | 1.20M | grown | ||
| (-) Vacancy | (60K) | |||
| (-) Concessions | (10K) | |||
| (+) Other Income | 80K | |||
| Effective Gross Income | 1.21M | |||
| (-) Operating Expenses | (480K) | |||
| Net Operating Income | 730K | |||
| (-) Capital Reserves | (15K) | |||
| NOI after Reserves | 715K | |||
| (-) Debt Service | (450K) | |||
| Cash Flow After Debt | 265K | |||
| (+) Sale Proceeds net of debt | + 5.2M | |||
| Cash Flow to Equity | 265K | 5.46M |
Plus a Sources & Uses table at acquisition and a Sources & Uses at exit.
VALIDATION: Row totals reconcile (EGI − OpEx = NOI). Year N+1 NOI used for exit valuation, not Year N.
============================================================ === PHASE 4: WATERFALL (for syndication deals) === ============================================================
If GP/LP partnership is configured, generate the waterfall.
Standard CRE waterfall (American or European — default European, which is simpler and LP-friendly):
Tier 1: Return of Capital — 100% to LP until LP has received back original equity
Tier 2: Preferred Return — 100% to LP until LP IRR = preferred rate (typically 8%)
Tier 3: First Promote — 70/30 (LP/GP) until LP IRR = 12% (or configured threshold)
Tier 4: Second Promote — 60/40 until LP IRR = 18%
Tier 5: Final Promote — 50/50 aboveOutput per LP and per GP:
VALIDATION: Sum of (LP + GP) distributions = total distributable cash flow. GP carry only kicks in after LP IRR hurdle met.
FALLBACK: If single-investor deal, skip this phase entirely.
============================================================ === PHASE 5: SENSITIVITY TABLES === ============================================================
Generate three 2D sensitivities (the deal-killers):
Each output as both a pandas DataFrame heatmap AND an Excel sheet with conditional formatting.
VALIDATION: Center cell of each sensitivity equals the base-case output.
============================================================ === PHASE 6: INVESTMENT MEMO === ============================================================
Generate memo.md (markdown) with these sections:
VALIDATION: Memo renders without dangling markdown. All numbers tie to the proforma.
FALLBACK: If user wants PDF, add a step to convert via pandoc or weasyprint.
============================================================ === SELF-REVIEW === ============================================================
Score 1–5:
If any < 4:
============================================================ === LEARNINGS CAPTURE === ============================================================
Append to ~/.claude/skills/cre-underwriting/LEARNINGS.md:
============================================================ === STRICT RULES === ============================================================
numpy.irr. Use numpy_financial.irr.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.