Finance substrate
Broomva agent-skills monorepo — 48 Tier-2 skills compatible with Claude Code, Codex, Cursor, Gemini CLI, Goose, Copilot. Layout follows anthropics/skills (agentskills.io spec). Install: npx skills add broomva/skills --skill <name>.
npx -y skills add broomva/skills --skill finance-substrateAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 3 stars3 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Personal finance and tax management substrate for Colombian residents. Imports bank transactions, tax certificates, and DIAN data. Projects annual tax liability (Form 210) with certificate-level accuracy. Handles password-protected PDFs from Colombian banks. Zero external paid services — all data stays local.
SKILL.md
22.5 KB, as published. Nobody here has run it
Finance Substrate
Self-hosted personal finance and Colombian tax management. No paid aggregators — imports from bank exports, parses tax certificates, and uses free open data APIs.
Data Sources
Automated (no manual export needed)
| Source | Method | Data | Cost |
|---|---|---|---|
| Gmail (9 institutions) | GWS CLI (gws gmail) | Salary payments, bank notifications, certificates, PILA confirmations | Free |
| DIAN MUISCA | agent-browser automation | Exogena XLSX, e-invoices XLSX, RUT PDF | Free |
| TRM (USD/COP) | datos.gov.co REST API | Daily exchange rates | Free |
Semi-automated (PDF parsing from user-provided files)
| Source | Method | Data | Cost |
|---|---|---|---|
| Davivienda | PDF certificate + CSV export | Cuentas, AFC, rendimientos, GMF | Free |
| Nubank Colombia | PDF certificate + CSV export | Rendimientos, retención, GMF | Free |
| Nequi | PDF certificate | Saldo, rendimientos | Free |
| RappiPay / RappiCard | PDF certificate | Saldo, deuda TC, cashback | Free |
| Skandia | PDF certificate (multi-page) | Pensión oblig/vol, cesantías, retiros | Free |
| Colmedica | PDF certificate | Medicina prepagada (Art. 387) | Free |
| Banco de Bogotá | PDF certificate | Intereses crédito | Free |
| Acciones & Valores | PDF certificate | Acciones, dividendos, FIC | Free |
| DolarApp/ARQ | Manual entry | USD balance (patrimonio exterior) | Free |
| PILA planillas | PDF from Compensar | SS contributions (salud, pensión, ARL, FSP) | Free |
Gmail institution coverage
| Institution | Email sender | Messages/year | Key data |
|---|---|---|---|
| Thera (salary) | thera | ~24 | USD payment amounts, dates |
| Davivienda | davivienda | ~16 | Monthly extractos (PDF), certs |
| Skandia | skandia | ~20 | Pension fund notifications |
| Nu Colombia | nu.com.co | ~20 | Account & rendimientos |
| Nequi | nequi | ~20 | Transaction confirmations |
| Compensar | compensar | ~18 | PILA payment confirmations |
| RappiPay | rappipay | ~11 | Payment notifications |
| Banco Falabella | falabella | ~15 | TC consumos, certs |
| DIAN | dian.gov.co | ~9 | Firma electrónica, RUT, códigos |
See references/gmail-data-sources.md for GWS CLI patterns, query syntax, and integration strategies.
PDF Password Convention
Colombian financial institution PDFs are typically password-protected with the account holder's cédula de ciudadanía (CC) number. When parsing certificates:
- First attempt: open without password (some PDFs like Davivienda are unprotected)
- Second attempt: use CC number as password
- The password is never stored in the skill repo or data files — prompted at runtime or passed via
--passwordflag
Institutions known to use CC-based PDF passwords:
- Skandia (pension obligatoria, voluntaria, cesantías)
- Colmedica (medicina prepagada)
- Nu Colombia (certificado tributario, reporte anual de costos)
- Nequi (certificado tributario)
- RappiCard / RappiCuenta (certificados tributarios)
- Banco de Bogotá (certificado tributario)
- Acciones & Valores (bursátil + fondos)
Institutions with unprotected PDFs:
- Davivienda (certificado tributario, extractos)
- DIAN (borrador, comprobantes)
- Finanseguro
Tax Declaration Strategy (Form 210)
Income Structure — Foreign Salary
For Colombian residents earning USD salary from a foreign employer:
- Ingresos brutos (R32): Gross COP value of all salary payments, converted at the official TRM rate on each payment date
- INCR (R33): Social security contributions as independent:
- Pension obligatoria (16% of IBC = 40% of gross)
- Salud obligatoria (12.5% of IBC)
- ARL (~0.522% of IBC, risk level I)
- Fondo Solidaridad Pensional (1% of IBC if income > 4 SMLMV)
- Source: pension fund certificate + monthly planillas
- FX losses: Deductible as cost of earning foreign income (difference between TRM and actual received amount)
Deduction Strategy — Maximizing R35 + R37
The primary tax optimization levers for persona natural:
-
AFC contributions (R35): Cuenta AFC (Ahorro Fomento a la Construcción)
- Aportes directos and aportes con contingente are both deductible
- Withdrawals for housing (destino vivienda) are tax-free under Art. 126-4 ET
- This is typically the single largest deduction available
- Source: bank AFC certificate (page showing aportes and retiros)
-
Voluntary pension (R35): Fondo de pensiones voluntarias
- Aportes with retención contingente are deductible
- Combined AFC + voluntary pension cap: 30% of gross income or 3,800 UVT (Art. 126-1 ET)
- Withdrawals before 10 years (or without meeting pension requirements) trigger retención contingente (7%)
- Source: pension fund voluntary certificate
-
25% renta exenta (R36): Art. 206.10 ET
- Automatic deduction of 25% on rentas de trabajo
- Capped at 790 UVT/month
-
Medicina prepagada (R39): Art. 387 ET
- Deductible up to 16 UVT/month
- Source: prepaid health provider certificate
-
E-invoice 1% deduction (R39): Art. 336 numeral 5 ET
- 1% of purchases paid electronically (tarjeta débito/crédito)
- Source: DIAN facturas electrónicas recibidas report
-
GMF deduction (R39): Art. 115 ET
- 50% of GMF (4x1000) paid is deductible
- Source: all bank certificates report GMF separately
-
Limitation (R41): Total exentas + deducciones capped at 40% of R34 or 5,040 UVT
- Strategy: maximize R35 (AFC + pension voluntaria) first since it's the most impactful before the cap binds
Patrimonio Strategy
Track all assets for R29 (patrimonio bruto):
- Bank accounts: all savings/checking account saldos at Dec 31
- Investment funds: pension voluntaria saldo, FICs
- Stocks: valor nominal of holdings
- Pension: cesantías saldo
- Vehicle: avalúo catastral from municipality
- Real estate: escritura value or avalúo
Deudas (R30): credit card balances, outstanding loans at Dec 31
Retenciones (R132)
Sum all retenciones from certificates:
- Pension fund: retención contingente + retención sobre rendimientos
- Banks: retención en la fuente on rendimientos financieros
- Other: any retención reported by third parties in exogena
Tip: the exogena report from DIAN aggregates retenciones reported by all third parties — use it to validate against individual certificates.
Anticipo Strategy
- R130: Anticipo paid in prior year (reduces current year saldo a pagar)
- R133: New anticipo = max(0, 75% of R126 - R132)
- First declaration year: 25%. Second year: 50%. Third year onwards: 75%
- Higher retenciones in current year reduce the anticipo for next year
Rendimientos Financieros (Rentas de Capital)
- Componente inflacionario: 50.88% of rendimientos (2024) are non-taxable (INCR)
- Banks report both total rendimientos and the non-taxable portion
- Source: each bank's certificate has a rendimientos + "no gravados" breakdown
- Don't forget: pension fund valorización counts as capital income
Skill Modes
1. import — Ingest bank transactions
Import CSV/OFX/XLSX from any supported bank into the unified ledger.
Scripts:
scripts/import_csv.py— Generic CSV/OFX parser with bank profiles inimporters/*.jsonscripts/import_declaracion.py— Bulk import from~/Dropbox/Declaracion/directory:- Bank consolidated XLSX (from bank PDF extraction scripts)
- Salary XLSX with USD→COP conversion details
- DIAN exogena XLSX (third-party reported data)
- DIAN e-invoices XLSX
- Transfer CSVs (international + national email notifications)
2. certificates — Parse tax certificates
Import certificados tributarios from financial institutions.
Script: scripts/import_certificates.py --year 2024 --password <CC>
Extracts data from all certificates in ~/Dropbox/Declaracion/<year>/ using regex patterns. Handles password-protected PDFs. Outputs aggregated tax inputs mapped to Form 210 rows.
3. trm — Fetch exchange rates
Script: scripts/fetch_trm.py
Fetches TRM from datos.gov.co free API. Supports single date, range, or last N days.
4. tax — Tax projection (Form 210)
Script: scripts/tax_projection.py --year 2024 --anticipo <amount>
Projects full Form 210 using salary data, certificates, and exogena:
- Maps output to actual DIAN row numbers (R29-R136)
- Models INCR from social security contributions
- Applies AFC + voluntary pension + 25% exempt income + medicina prepagada
- Calculates anticipo renta for following year
- Compares against DIAN borrador when available
5. categorize — Classify transactions
Apply or update categorization rules on uncategorized transactions.
6. summary — Financial reports
Aggregate transactions by category, account, currency with multi-period comparison.
7. dian-scrape — MUISCA data download
Browser automation for DIAN portal data extraction (requires agent-browser skill).
Capabilities (post-login):
- Download exogena XLSX (third-party reported income, patrimony, withholdings)
- Download e-invoices received report
- Download withholding certificates
- Retrieve RUT PDF
- Query filed declarations and payment history
Login flow: Uses agent-browser to navigate the WebIdentidadLogin SPA → OAuth callback → JSF portal. Document type dropdown must be clicked (not select-ed) to avoid form reset. Sessions can be persisted with agent-browser state save.
See references/dian-muisca-automation.md for the complete technical reference including URL patterns, error codes, security measures, and legal considerations.
8. dian-fill — Form 210 Declaration Filing
Automate filling and submitting the declaración de renta (Form 210) on DIAN MUISCA using agent-browser.
Script: scripts/fill_form210.py --year 2024 --anticipo 19287000
How it works:
- Runs
tax_projection.pyto compute all casilla values - Maps each casilla to the correct wizard step via
templates/form-210-schema.json - Generates step-by-step
agent-browsercommands:- Navigates to each step via JS click on step counter elements
- Snapshots to discover field refs (refs change between sessions)
- Fills editable casillas with projected values (DIAN-rounded to thousands)
- Skips auto-computed casillas (DIAN calculates them)
Output modes:
--dry-run— Human-readable table of casilla → value mappings- Default — Shell script with
agent-browsercommands (pipe tobash) --json— Machine-readable mapping for programmatic use
Form 210 wizard structure (15 steps):
| Step | Section | Key casillas |
|---|---|---|
| 1 | Datos Declarante | 5-12, 24 (actividad económica), 286 (género) |
| 2 | Deducciones sin limitantes | 28, 297 (e-invoice), 245, 247, 249, 251, 299 |
| 3 | Patrimonio | 29, 30, 31 |
| 4 | Rentas de trabajo | 32-42 |
| 5 | Rentas de trabajo (no relación laboral) | 43-57 |
| 6 | Rentas de capital | 58-73 |
| 7 | Rentas no laborales | 74-90 |
| 8 | Cédula general | 91-97 |
| 9 | Pensiones | 99-103 |
| 10 | Dividendos | 104-120 |
| 11 | Liquidación privada | 121-133 |
| 12 | Ganancias ocasionales | 112-115 |
| 13 | Anticipo | 130, 133 |
| 14 | Saldo a pagar / favor | 134-141 |
| 15 | Firma y presentación | Electronic signature + submit |
Typical workflow:
# 1. Open headed browser (manual login required for now)
agent-browser --headed --session dian open "https://muisca.dian.gov.co/"
# Log in manually in the browser window
# 2. Navigate to Form 210 creation
# Dashboard → "Presentar Declaración de Renta" → Select year → Crear
# 3. Generate fill commands from tax projection
python3 scripts/fill_form210.py --year 2024 --dry-run # Preview values
python3 scripts/fill_form210.py --year 2024 > /tmp/fill-210.sh # Generate script
# 4. Execute step by step (review each step before advancing)
# Each step: snapshot → fill casillas → verify → next step
# The script uses placeholder refs (<REF_casilla_NNN>) that must be
# replaced with actual @eN refs after each snapshot
# 5. After all steps: Firmar → Presentar → Pagar
Important notes:
- DIAN rounds all values to thousands (no decimals) — the script does this automatically
- Field refs (
@eN) change between sessions — always snapshot before filling - For already-filed years (like 2024), DIAN only allows "Corrección" — not new "Inicial"
- The Firmar step requires electronic signature (manual intervention)
- Always review values before submitting — the script fills a draft, it does not auto-submit
See templates/form-210-schema.json for the complete casilla-to-ET-article mapping.
9. optimize — Deduction Optimizer
Script: scripts/optimize_deductions.py --gross-income <COP> --year 2024
Finds the optimal AFC + voluntary pension contribution split to minimize tax.
What it computes:
- Maximum useful contribution before the 1,340 UVT cap binds (Art. 336 Num. 3, Ley 2277/2022)
- Tax savings vs. zero contributions
- Marginal benefit analysis (tax saved per additional $1M COP)
- Warning when the global cap is the binding constraint
Key constraint hierarchy:
- AFC + voluntary pension ≤ 30% of gross income or 3,800 UVT (Art. 126-1 + 126-4)
- Total exentas + deducciones ≤ 40% of renta líquida or 1,340 UVT (Art. 336)
- 25% renta exenta ≤ 790 UVT/year (Art. 206 Num. 10)
- The 1,340 UVT global cap is typically the binding constraint for incomes above ~$150M COP
10. self-heal — Validation and Anomaly Detection
Script: scripts/self_heal.py --year 2024
Detects data quality issues and signals improvements for agents to act on.
Checks performed:
- Parser health: validates all
parsers/*.jsondefinitions (schema, methods, no duplicates) - Extraction confidence: flags parsers that extracted mostly zeros (PDF format likely changed)
- Expected non-zero fields: catches silent failures (e.g., rendimientos = $0 for a bank that should have them)
- Cross-source validation: compares retenciones and pension amounts across certificates, exogena, and planillas — flags >5% discrepancies
- XLSX schema validation: checks that DIAN export column structure matches expectations before import
- Projection sanity: verifies arithmetic (R34 = R32 - R33), cap compliance (R41 ≤ 1,340 UVT), no negatives
Self-healing loop:
- Run
self_heal.pyafter every import cycle - Issues logged to
.control/improvement-log.jsonlwith severity and suggestions - Agents (Claude or any LLM) read the log and take corrective action:
unknown_institution→ create newparsers/<name>.jsonlow_extraction_confidence→ update parser regex patterns for changed PDF formatexpected_nonzero_field→ investigate specific field in parser definitionretenciones_mismatch→ check for missing certificate or exogena updateexogena_schema_drift→ update column mappings in import script
- After fix, re-run
self_heal.pyto verify the issue is resolved
For agents reading this skill:
When invoked, always run python3 scripts/self_heal.py --year <year> after importing data. If issues are found, read .control/improvement-log.jsonl for the latest signals and fix the root cause before proceeding with tax projection or form filling. The control metalayer in .control/commands.yaml defines the actuators (create-parser, update-parser, fix-xlsx-schema) that map to each signal type.
11. budget — Monthly Budget Planner
Script: scripts/budget_planner.py --monthly-usd 8000 --year 2025
Computes monthly budget allocation for a Colombian resident earning USD salary.
Allocates:
- Parafiscales PILA (fixed monthly obligation)
- AFC contribution (monthly portion of annual optimal amount)
- Voluntary pension (monthly portion)
- Tax savings fund (saldo a pagar / months to deadline)
- Available for living expenses (remainder)
Outputs a formatted table with COP, USD, and percentage of income for each category.
12. patrimonio — Net Worth Calculator
Script: scripts/patrimonio_calc.py --year 2024 --detail
Aggregates patrimonio from all data sources for Form 210 R29/R30/R31.
Sources:
- Certificates: bank account saldos, investment funds, pension funds
- Exogena: real estate (Marval), vehicle (Bogotá avalúo), stocks (Ecopetrol), third-party reported saldos
- Manual entries:
--add-asset "Cash" 5000000 --add-debt "Loan" 3000000
Deduplication: When the same asset appears in both certificates and exogena, uses the higher value and flags the overlap.
13. report — Accounting Report Generator
Generates comprehensive accounting and tax report in Markdown format, covering:
- Executive summary (year-over-year comparison)
- Monthly salary detail with TRM conversion
- Social security (parafiscales) breakdown
- Patrimonio (assets and liabilities)
- Form 210 comparative table with ET article references
- Deduction strategy analysis
- Monthly budget plan with tax savings fund
- Filing calendar and data source inventory
14. gmail — Email Document Collector
Script: scripts/gmail_collector.py --year 2025
Searches Gmail for tax-relevant documents from all financial institutions using GWS CLI (gws).
Sources searched:
- Thera — salary payment confirmations (extracts USD amount and employer)
- Davivienda — extractos, certificados, transaction notifications
- Nu Colombia — account notifications
- Nequi — transaction notifications
- RappiPay/RappiCard — payment notifications
- Skandia — pension fund notifications
- Compensar — PILA/parafiscales confirmations
- DIAN — official notifications (firma electrónica, RUT, códigos)
- Banco Falabella — certificates and statements
Capabilities:
- Search by year with automatic date filtering
- Extract salary amounts from Thera payment emails ($USD parsed from body)
- Download PDF/XLSX attachments to
~/Dropbox/Declaracion/<year>/Gmail/ - Filter by single source:
--source thera
Requires: GWS CLI installed and authenticated (npx skills add googleworkspace/cli, gws auth login)
15. invoice — DIAN e-invoicing
Issue UBL 2.1 invoices via DIAN SOAP (requires facho + digital certificate).
File Structure
finance-substrate/
├── SKILL.md # This file
├── skill.json # Schema definition
├── scripts/
│ ├── import_csv.py # Bank CSV/OFX parser
│ ├── import_declaracion.py # Bulk import from Declaracion/
│ ├── import_certificates.py # Tax certificate PDF parser
│ ├── import_planillas.py # PILA social security planilla parser
│ ├── parse_engine.py # Declarative parser interpreter
│ ├── fetch_trm.py # TRM API client
│ ├── tax_projection.py # Form 210 tax engine (95% accuracy)
│ ├── fill_form210.py # Agent-browser commands for DIAN wizard
│ ├── optimize_deductions.py # AFC + vol. pension optimizer
│ ├── budget_planner.py # Monthly budget allocation with tax savings
│ ├── patrimonio_calc.py # Net worth calculator (R29/R30/R31)
│ ├── gmail_collector.py # Gmail search for tax docs & salary payments
│ └── self_heal.py # Validation, anomaly detection, self-healing
├── importers/
│ ├── davivienda.json # Column mappings & date format
│ ├── nubank.json # Column mappings & date format
│ ├── nequi.json # Column mappings & date format
│ └── arq.json # Column mappings & date format
├── templates/
│ ├── tax-tables-2024.json # DIAN tax brackets (UVT $47,065)
│ ├── tax-tables-2025.json # DIAN tax brackets (UVT $49,799)
│ ├── tax-tables-2026.json # DIAN tax brackets (projected)
│ └── categories.json # Default category taxonomy (40+ rules)
├── references/
│ ├── dian-calendar.md # Filing deadlines by NIT suffix
│ ├── dian-muisca-automation.md # MUISCA browser automation reference
│ ├── estatuto-tributario.md # ET article citations for all Form 210 rows
│ ├── gmail-data-sources.md # Gmail/GWS CLI patterns for all institutions
│ └── data-architecture.md # Document flow and storage governance
├── reports/
│ └── financial-report-2025.md # Comprehensive annual report with projections
└── README.md # Setup & usage
Data Directory (user-local, not in skill repo)
~/.finance-substrate/
├── ledger/
│ ├── transactions.jsonl # Append-only unified transaction log
│ ├── accounts.json # Account registry
│ └── rules.json # Categorization rules
├── tax/
│ ├── salary-history.jsonl # Monthly salary payments with FX details
│ ├── certificates.jsonl # Parsed institution certificates
│ ├── exogena.jsonl # DIAN third-party reports
│ ├── withholdings.jsonl # Retenciones tracking
│ └── projections/ # Saved tax projections
├── fx/
│ └── trm-history.jsonl # TRM rate history
└── invoices/
├── issued/ # Outgoing e-invoices
└── received/
└── e-invoices.jsonl # DIAN e-invoices received
Related Skills
- wealth-management — Compounds on this skill for long-term wealth building. Reads certificates, patrimonio, and salary data to run compound growth projections, Monte Carlo simulations, goal-based planning, and asset allocation optimization.
- investment-management — Full-stack investment analysis and execution. Security screening, philosophy-based scoring, market data, backtesting, portfolio optimization, and trade execution across stocks, crypto, and prediction markets.
Dependencies
- Python 3.10+
openpyxl— Excel parsing (required for declaracion import)pymupdf— PDF text extraction (required for certificate parsing)facho— DIAN SOAP client (optional, only for e-invoicing)agent-browserskill (optional, only for DIAN scraping)- No paid services. No API keys. All data stays local.