t12-to-database
Transforms a tokenized/extracted trailing-twelve-month operating statement into validated account-level monthly records. A constrained preset over operating-statement-to-database: it asserts line_type=actual over a (possibly partial) twelve-month trailing window, excludes Total/YTD aggregate columns, flags partial-year/lease-up as a warning (never synthesizing missing months), normalizes the expense sign convention so NOI is not inflated, and maps accounts to the canonical chart of accounts for the NOI bridge and the rent-roll tie-out. Triggers on 'load this T-12', 'normalize the trailing twelve into the database', or 'T-12 to warehouse'.
Best use case
t12-to-database is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Transforms a tokenized/extracted trailing-twelve-month operating statement into validated account-level monthly records. A constrained preset over operating-statement-to-database: it asserts line_type=actual over a (possibly partial) twelve-month trailing window, excludes Total/YTD aggregate columns, flags partial-year/lease-up as a warning (never synthesizing missing months), normalizes the expense sign convention so NOI is not inflated, and maps accounts to the canonical chart of accounts for the NOI bridge and the rent-roll tie-out. Triggers on 'load this T-12', 'normalize the trailing twelve into the database', or 'T-12 to warehouse'.
Teams using t12-to-database should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/t12-to-database/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How t12-to-database Compares
| Feature / Agent | t12-to-database | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Transforms a tokenized/extracted trailing-twelve-month operating statement into validated account-level monthly records. A constrained preset over operating-statement-to-database: it asserts line_type=actual over a (possibly partial) twelve-month trailing window, excludes Total/YTD aggregate columns, flags partial-year/lease-up as a warning (never synthesizing missing months), normalizes the expense sign convention so NOI is not inflated, and maps accounts to the canonical chart of accounts for the NOI bridge and the rent-roll tie-out. Triggers on 'load this T-12', 'normalize the trailing twelve into the database', or 'T-12 to warehouse'.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# T-12 to Database
You are a CRE data engineer who turns an extracted trailing-twelve-month operating statement into trustworthy, source-cited, account-by-period records. A T-12 is not its own object — it is a CONSTRAINED PRESET over `operating-statement-to-database`: the same general operating-statement model, pinned to `line_type=actual` over a (possibly partial) trailing-twelve-month window. So this skill does not duplicate the model; it references it and adds the constraints that make a trailing-twelve specifically trustworthy. You never synthesize a missing month, you never let a Total column masquerade as a period, you never inflate NOI by flipping a sign or folding in capex, and you never guess an account you cannot map.
This skill is backed by the same deterministic, stdlib-only calculators as the root: `normalize_tokens.py` (with `doc_type: t12`), `validate_payload.py`, `grade_ingestion.py`, and `map_charge_codes.py`. Each is a pure `calculate_x(dict) -> dict`, reads its selectors from `--json`, holds no state, makes no network call, and reads no wall clock. Same input dict in, byte-identical JSON out.
## When to Activate
Explicit triggers:
- "load / ingest / normalize this T-12 (or trailing twelve) into the database (or warehouse)"
- "get this T-12 ready for the rent roll <-> T-12 tie-out"
- "normalize the trailing twelve actuals to our chart of accounts"
Implicit triggers:
- An extracted operating statement is specifically a trailing-twelve-month actuals run (twelve monthly columns of recognized actuals, possibly partial for a lease-up asset) and must become typed, validated, account-by-period records before underwriting or reconciliation.
Do NOT activate for:
- A statement that carries budget, reforecast, prior-year, or underwritten columns, a non-monthly grain, or several scenarios side by side — that is the general object, use `operating-statement-to-database`.
- Reconciling an already-normalized rent roll against an already-normalized T-12 — use `rent-roll-t12-tieout`.
- Rent-roll ingestion — use `rent-roll-to-database`.
- Pure extraction of tokens FROM a source document — that is upstream, `document-to-data-room-extractor` / `t12-normalizer`.
## Input Schema
Identical to the general operating-statement schema, with `doc_type: t12` selected. The preset only narrows the expected shape (twelve monthly periods of `line_type=actual`); it does not add fields.
| Field | Type | Required | Notes |
|---|---|---|---|
| `doc_type` | string | yes | `t12` (selects the preset and its 12-period integrity check) |
| `as_of` | string | yes | ISO date; flows unchanged into provenance timestamps. No wall clock is used. |
| `run_id` | string | no | Stamps `extraction_run_id` on every record. |
| `tenant_id` | string | no | Tenancy/workspace label (path-validated; NOT an auth token). |
| `source` | object | no | `{document_id, file_name, document_type, table_id}` for provenance. |
| `property` | object | no | `{property_id, property_type, rentable_sf, units, market}`. |
| `periods` | array | no | The twelve monthly labels (e.g. `2025-01 … 2025-12`); aggregate columns are excluded here, not counted. |
| `aggregate_columns` | array | no | Column labels to exclude as aggregates (defaults to `total`, `ytd`, `annual`, `annualized`). |
| `expense_sign_convention` | string | no | `positive_magnitude` (default), `signed_negative`, or `debit_credit_normal_balance`. |
| `lines` | array | yes | One object per source statement line: `account_code`, `account_name`, optional `statement_section`, `line_type` (default `actual`), and `amounts` keyed by month. |
For the full model behind these fields, see `../operating-statement-to-database/references/operating-statement-model.md` and `../operating-statement-to-database/references/chart-of-accounts-taxonomy.md`. For the constraints this preset adds, see `references/t12-validations.md`.
## Process
The preset runs the general operating-statement process with `doc_type: t12` and tightens four steps. It does not re-implement the model.
### Step 1: Detect the twelve monthly periods (aggregate-aware)
Resolve the period set and EXCLUDE every aggregate column (`total` / `ytd` / `annual` / `annualized`). A trailing twelve carries twelve monthly periods; the count check is the preset's signature constraint (Step 5), not a substitute for excluding aggregates.
### Step 2: Assert line_type=actual
A T-12 is recognized actuals. Lines default to `line_type=actual`; the NOI aggregates and the downstream rent-roll tie-out read ONLY the `actual` line_type, so any non-actual column does not enter the trailing-twelve NOI.
### Step 3: Normalize the sign convention
Convert every amount to the canonical convention (expenses, capex, debt service, and distributions as positive magnitudes) so a bracketed-negative or signed-negative expense column does not flip an expense into revenue and the trailing-twelve NOI is not inflated.
### Step 4: Map accounts to the chart of accounts
Map each line to a canonical account — direct GL code (high confidence), name inference (medium, flagged), or the `unmapped` bucket (flagged, never dropped). The mapped account fixes the `statement_section`, keeping capex out of NOI.
### Step 5: Validate the twelve-period integrity, then grade
`validate_payload` runs the preset's period-integrity check: exactly twelve monthly periods passes; FEWER than twelve is a WARNING (partial-year / lease-up, carried as a gap, never synthesized); MORE than twelve is a CRITICAL (an aggregate column was not excluded). It recomputes `NOI == revenue - operating_expense` with below-the-line excluded, and reconciles `Total == sum of months` as a separate check against any excluded aggregate column. `grade_ingestion` then scores period integrity, account-mapping coverage, sign convention, NOI classification, duplicate detection, and provenance as a weakest-link A/B/C letter plus a 0-100 score. The reconciliation dimension is N/A — re-weighted out, never scored zero — when no paired rent roll is present.
### Step 6: Hand off
The canonical payload feeds `rent-roll-t12-tieout` (the revenue tie-out reads the `actual` line_type) and the target-model emitters for the chosen profile.
## Output Format
A canonical T-12 payload: `{doc_type: "t12", records (account x month lines), aggregates, periods, issues}`. Each `records[]` line carries `account_code`, `raw_account_name`, `canonical_account`, `statement_section`, `line_type`, `fiscal_period` (`YYYY-MM`), `amount` (sign-normalized), and the provenance bundle with `source_ref` in `data-room/<doc>#<anchor>` form. `aggregates` carries `periods_present`, `periods_expected` (12), `expense_sign_convention`, `revenue_actual`, `operating_expense_actual`, and `noi_actual`. Plus: an account-mapping report, a validation report (with the period-integrity verdict), a data-quality grade (A/B/C + 0-100), and a human-review queue.
## Red Flags
- A Total / YTD column counted as the thirteenth period — more than twelve periods is a CRITICAL signaling an aggregate column was not excluded.
- A partial-year or lease-up month annualized or back-filled — fewer than twelve periods is a carried gap and a warning, never a synthesized month and never a partial month multiplied by twelve.
- A bracketed-negative expense column flipping an expense into revenue and inflating the trailing-twelve NOI — normalize the sign convention first.
- A capex, debt-service, or distribution line folded into NOI — below-the-line items stay out of the revenue-minus-operating-expense computation.
- A budget or reforecast column entering the trailing-twelve NOI — only the `actual` line_type feeds the aggregates; if the statement carries non-actual scenarios, the general `operating-statement-to-database` object is the right entry point.
- An unmapped account silently dropped or guessed — flag it to the unmapped bucket; never fabricate the mapping and never drop the dollars.
## Chain Notes
Upstream (produce the tokens this skill ingests): `operating-statement-to-database` (this skill is a preset over that root; the model lives there), `t12-normalizer` (the trailing-twelve reader), and `document-to-data-room-extractor` (typed extraction + the PII boundary this layer mirrors).
Downstream (consume this skill's records): `rent-roll-t12-tieout` (the revenue tie-out, which reads ONLY the `actual` line_type to reconcile contractual in-place rent against recognized accrual), `document-to-database` (orchestration + target-model emission), and `acquisition-underwriting-engine` (the recognized-accrual side of the cash-flow spine).Related Skills
rent-roll-to-database
Transforms a tokenized/extracted rent roll into validated, typed, auditable, database-ready records: a multi-line charge schedule (base rent, CAM/tax/insurance recoveries, percentage rent, parking, storage) mapped to the canonical chart of accounts, lease- and unit-level facts, GPR and occupancy aggregates, a data-quality grade, and a target-model load plan. Tenant identity is pseudonymized; per-unit natural-person data never leaves the boundary. Triggers on 'load this rent roll into the database', 'normalize the rent roll to our schema', 'rent roll to warehouse', or when extracted rent-roll tokens need to become structured records before underwriting or tie-out.
operating-statement-to-database
Transforms a tokenized/extracted operating statement (any line type: actual, budget, reforecast, prior-year; any period grain; monthly, quarterly, annual-summary, or multi-scenario) into validated, account-level, period-level database records mapped to the canonical chart of accounts. Format-aware period handling excludes Total/YTD aggregate columns, normalizes the expense sign convention, detects duplicate/subtotal lines, and keeps capex and debt service below the NOI line. Triggers on 'load this operating statement', 'normalize the P&L to our accounts', or when extracted operating-statement tokens must become governed account-level records.
document-to-database
Executable orchestrator that turns tokenized/extracted CRE document content (rent rolls, T-12s, operating statements, Prose Frontier narrative artifacts) into validated, typed, auditable, target-model-ready database payloads. Canonical flow: classify, identify fields, coerce types, normalize, map charge codes to the chart of accounts, validate, score confidence, emit an issue report, map to a target database model, emit optional SQL DDL and a load plan, self-grade, and route ambiguous items to a human-review queue. Backed by deterministic stdlib calculators; fail-closed when a citation cannot be made; tenant identity pseudonymized. Triggers on 'turn these documents into a database', 'ingest this data room to our schema', 'document to warehouse', or when extracted tokens must become governed structured data.
workout-playbook
Produces a lender-side workout and restructuring playbook for distressed CRE loans. Maps all resolution paths (forbearance, A/B note split, DPO, deed-in-lieu, foreclosure, note sale), models NPV of each, assesses borrower leverage, and recommends optimal strategy with timeline.
Work Order Triage
Classifies work order urgency from free-text descriptions, assigns priority (P1-P4) with SLA deadlines, estimates cost, checks lease responsibility, and routes to the correct approval path.
warehouse-to-exhibit-mapper
Maps validated, warehouse-ready tabular datasets into deck-ready EXHIBIT specifications and slide inputs. Selects table vs. chart per exhibit, names axes and series, maps source dataset columns to exhibit fields, binds each exhibit to a target slide, and carries provenance THROUGH so every exhibit cell keeps its source_ref and classification. Triggers on 'map this to exhibits', 'turn the dataset into slides', 'build the exhibit specs', or when a validated dataset must become charts and tables for a committee deck. It specifies exhibits; it does not render pixels or compose the full deck.
vendor-invoice-validator
Validates vendor invoices against contract terms, scope of work, and market rates. Checks arithmetic, rate compliance, scope authorization, duplicate detection, GL coding, and NTE/cap limits. Assigns APPROVED, APPROVED WITH FLAGS, or HOLD FOR REVIEW verdict.
variance-narrative-generator
Generates ownership-ready variance narratives from budget-vs-actual reports. Screens for materiality, classifies variances as timing/permanent/one-time/trend, projects full-year NOI impact, and drafts investor-quality explanations.
transfer-document-preparer
Prepare entity transfer documents, closing document packages, and assignment agreements for CRE acquisitions. Branches by entity type (LLC, LP, DST, UPREIT, C-Corp, S-Corp, trust), ownership chain depth, 1031 exchange timing constraints, state-specific recording and transfer tax requirements, and FIRPTA withholding obligations. Triggers on 'transfer docs', 'deed preparation', 'entity authorization', 'closing documents', 'assignment of leases', 'FIRPTA', '1031 QI assignment', 'conveyance document', or when given PSA closing conditions, entity formation documents, or ownership chain diagrams.
title-commitment-reviewer
Analyze ALTA title commitments, surveys, and Schedule B exceptions for CRE acquisitions. Identifies title defects, chain breaks, lien conflicts, and cure requirements. Triggers on 'title commitment', 'Schedule B exceptions', 'title review', 'title exceptions', 'encumbrances', 'survey cross-reference', 'title chain', 'mechanic's lien', 'title cure', or when given a title commitment document, survey, or lien search results.
term-sheet-builder
Draft and negotiate CRE financing term sheets from lender quotes. Branch by loan type (agency, CMBS, bank balance sheet, bridge, construction, mezzanine), borrower entity, and deal strategy. Interrogate rate preference, hold period, recourse tolerance, and stack complexity before drafting. Triggers on 'draft term sheet', 'lender quote', 'rate lock', 'negotiate terms', 'loan terms', 'prepayment', 'IO period', 'spread', 'carve-outs', or when user provides a lender quote for review.
tenant-retention-engine
Generates comprehensive tenant retention strategies with per-tenant renewal probability scoring, retention NPV analysis, WALT impact quantification, DSCR covenant monitoring, competitive intelligence, game theory framing for multi-tenant dynamics, and blend-and-extend modeling. Includes backfill mode (lease-up war room) when retention fails. Triggers on 'tenant retention', 'lease expiration', 'renewal strategy', 'WALT', 'rollover risk', or significant lease rollover exposure.