# Capacite Emprunt Fr

> Generate French mortgage capacity per HCSF rules (35% DTI, 25-year cap) with live rates. Use when a buyer asks how much to borrow; outputs 3 scenarios (15/20/25 ans). Don't use for consumer credit, debt consolidation, non-France loans, tax advice.

- Skill: `luongnv89/capacite-emprunt-fr` (Agent Skill, multi-file: 14 files)
- Install (CLI): `npx skillmds@latest add luongnv89/capacite-emprunt-fr`
- Raw SKILL.md: https://api.skillmd.com/api/skills/luongnv89/capacite-emprunt-fr/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: MIT
- Author: luongnv89 (https://skillmd.com/u/luongnv89)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/luongnv89/capacite-emprunt-fr

---


# capacite-emprunt-fr — Capacité d'emprunt immobilier (France)

Estimate how much a buyer can borrow from a French bank, respecting current HCSF rules and today's Meilleurtaux/Empruntis barème.

## When to Use

- "Combien je peux emprunter pour acheter ?" / "quelle est ma capacité d'emprunt ?"
- "Avec X € de revenus et Y € de crédit voiture, je peux acheter à combien ?"
- "Simule mon prêt immobilier sur 15 / 20 / 25 ans."
- "Quel est mon taux d'endettement maximal selon le HCSF ?"
- "Voilà mon bulletin de salaire / tableau d'amortissement / avis d'impôt — combien je peux emprunter ?"
- "Recalcule avec mon profil existant" / "Charge mon profil <name>" / "Sauve ce profil sous <name>"
- The user invokes `/capacite-emprunt-fr` with or without arguments.

Do **not** trigger for: crédit à la consommation, rachat / regroupement de crédits, prêt professionnel, simulation immobilière hors France (Belgique, Suisse, Luxembourg), ou questions de fiscalité.

## Output: a single FR markdown briefing

Write the result **inline in the conversation** as a single French markdown briefing — no HTML file, no separate report. Keep it under one screen so the user can act on it.

Sections, in order:

1. **Vos données** — recap of inputs (revenus, charges, apport, profil).
2. **Règles HCSF appliquées** — with "Source au [date]" line citing HCSF and Meilleurtaux.
3. **3 scénarios** — markdown table for 15/20/25 ans. Columns: durée, taux nominal, taux assurance, mensualité, capital empruntable, prix max bien (capital + apport − frais de notaire estimés), coût total des intérêts.
4. **Marge de manœuvre HCSF** — one paragraph: banks may deviate up to 20% of new loans per quarter (≥70% reserved for résidence principale, 30% for primo-accédants), so an atypical profile can still pass.
5. **Avertissement** — one short sentence: "Ce calcul est indicatif. Seule une banque ou un courtier valide votre dossier."

See `references/output-template.md` for the exact structure to render.

## Prerequisites

- `python3` available on PATH; the bundled scripts require `markitdown` for PDF parsing.
- WebFetch access to `legifrance.gouv.fr` and `empruntis.com`. Cloudflare-protected sources (economie.gouv.fr, cafpi.fr) return 403 and are listed only as secondaries — do not rely on them.
- Write access to `~/.francais-skills/profiles/` (created at mode 0700 on first use). The profile store will fail with a descriptive error if the directory is read-only.

## Error handling

- **WebFetch timeout or 403** — retry once. If it still fails, fall back to `references/sources.md`, mark the report line `× fallback`, and warn the user the rate is stale.
- **`compute_capacity.py` non-zero exit** — surface stderr to the user with the offending input. Never patch the script's output silently; ask the user to validate the input that triggered the error.
- **PDF parser returns empty fields** — do not guess; ask the user for the missing figure directly. Confirm any extracted number before using it.
- **Profile save failure** — the script rolls back to the pre-edit file and prints a caution line. Tell the user the slug was not written and ask whether to retry under a different name.
- **Conflicting inputs** (e.g. bulletin says 3 000 € but user types 4 000 €) — flag the discrepancy, ask which to use, never silently override.

## Workflow

Always follow these phases in order. Each phase ends with a one-line status before moving on.

### Phase 0 — Pick or create a profile

Profiles live at `~/.francais-skills/profiles/{slug}.json` and persist across conversations so the user never re-enters the same numbers twice. Schema is documented in `references/profile-schema.md`. CRUD via `scripts/profile_store.py`. See `references/inputs.md` for the decision tree (`recalcule`, `sauve sous`, no-mention, PDF-attached).

### Phase 1 — Collect/update inputs

Three input modes: **A** interactive (AskUserQuestion in one batch), **B** PDFs (run the matching parser script per attached file), or **C** load profile (already done in Phase 0). Full required-fields list, parser commands, and validation rules live in `references/inputs.md`. Always confirm extracted figures with the user before computing — a single misread comma can swing the answer 10×.

### Phase 2 — Fetch fresh data (mandatory)

Use WebFetch **on every invocation** — never trust cached values from prior turns. Fetch in parallel:

1. **HCSF rules** — primary URL, extraction prompt, fallbacks: see `references/sources.md`.
2. **Barème des taux** — primary URL, secondary fallback, blocking notes: see `references/sources.md`.

Record the **date of fetch** for each source. Both go into the output's "Source au [date]" line. If both primary and secondary fail, fall back to the reference values in `references/sources.md` and **explicitly tell the user** the source was unreachable so they know the numbers may be stale.

### Phase 3 — Compute (deterministic)

Run `scripts/compute_capacity.py` with the collected inputs and fetched values. The agent **must not do this math inline** — always shell out to the script so the calculation is reproducible and testable.

```bash
python3 scripts/compute_capacity.py \
  --revenus 4500 --revenus2 0 --charges 250 --apport 50000 \
  --type-bien ancien --assurance 0.0034 \
  --taux-15 0.0320 --taux-20 0.0333 --taux-25 0.0343 \
  --dti-max 0.35
```

The script sums income, computes the 35% DTI cap assurance comprise, subtracts existing monthly debts, back-solves the amortization formula for each duration (15/20/25 ans), and adds apport minus frais de notaire to get the max property price. Output is JSON on stdout that the agent reads into the template.

### Phase 4 — Render

Render the FR markdown briefing using `references/output-template.md`. Do not invent rules, dates, or rates that weren't fetched in Phase 2 — every regulatory claim must carry a "Source au [date]" line tied to the WebFetch result.

### Phase 5 — Persist profile

After rendering, save the (possibly updated) profile back to `~/.francais-skills/profiles/{slug}.json` via `profile_store.py save`. What to persist vs. what to skip is documented in `references/inputs.md` and `references/profile-schema.md`.

### Phase 6 — Status report

End with the Step Completion Report below so the user sees what was loaded, fetched, computed, and saved.

## Step Completion Report

After Phase 6, emit:

```
◆ Capacité d'emprunt FR (terminé)
··································································
  Profil:                 √ chargé (<slug>) / √ nouveau / × pas de profil
  Inputs collectés:       √ pass (mode A interactif / B PDFs / C profil)
  HCSF récupéré:          √ pass (source du YYYY-MM-DD)
  Taux récupérés:         √ pass (source du YYYY-MM-DD)
  Calcul script:          √ pass
  3 scénarios rendus:     √ pass
  Profil sauvé:           √ pass (<slug>) / — non sauvé
  ____________________________
  Result:                 PASS
```

If a fetch fell back to references/, mark that line with `× fallback — using stale data from <date>` instead of √ pass.

## Acceptance Criteria

Verify each before declaring done:

- Vos données section lists revenus, charges, apport, type de bien — every supplied or extracted field appears with its numeric value.
- HCSF block names **35% DTI**, **25-year max**, **20% flexibility**, each with a "Source au YYYY-MM-DD" line from the WebFetch run.
- 3-scenario table has exactly three rows (15/20/25 ans) and the columns listed in `references/output-template.md`.
- Mensualité on each row ≤ 35% of total monthly income (assurance comprise) minus existing debts.
- Closing "Ce calcul est indicatif" disclaimer appears verbatim.
- `scripts/compute_capacity.py` was invoked exactly once (no inline math). Its JSON matches the table numbers.
- A profile was loaded or saved (never both skipped); the Step Completion Report shows the slug.
- Output is markdown, **not HTML**, and fits in one screen.

## Expected output

A short FR markdown briefing with the five sections listed in *Output* above. Sample shape (numbers illustrative):

```markdown
## Vos données
- Profil : couple co-emprunteurs · 4 800 € + 2 100 € = 6 900 € · charges 280 € · apport 60 000 € · ancien

## Règles HCSF appliquées
- DTI max **35%** · durée max **25 ans** · marge flexibilité **20%** — Source au 2026-05-14

## 3 scénarios
| Durée  | Taux | Mensualité | Capital | Prix max | Intérêts |
|--------|------|------------|---------|----------|----------|
| 15 ans | 3.20 % | 2 135 € | 273 400 € | 309 800 € | 110 900 € |
| 20 ans | 3.33 % | 2 135 € | 339 100 € | 375 500 € | 178 200 € |
| 25 ans | 3.43 % | 2 135 € | 393 800 € | 430 200 € | 247 700 € |

## Marge de manœuvre HCSF
Les banques peuvent déroger jusqu'à 20% de leurs nouveaux crédits par trimestre…

## Avertissement
Ce calcul est indicatif. Seule une banque ou un courtier valide votre dossier.
```

See `references/output-template.md` for the full column set and formatting rules.

## Edge cases

Critical cases the agent must detect:

- **Mensualité > 35% DTI on every duration** — emit scenarios with the max-allowed payment and flag over-budget. Never zero out a row.
- **Apport ≥ price of target bien** — surface as "pas besoin d'emprunter"; ask the user how to proceed.
- **RFR ÷ 12 diverges from bulletin × 13 by >20%** — flag the discrepancy; keep bulletin-derived income unless user overrides.
- **Both Phase-2 sources fail** — fall back to `references/sources.md`, mark report line `× fallback`, warn the user the rate is stale.
- **User asks for advice** ("should I take 20 or 25 ans?") — refuse to recommend a duration, bank, or whether to buy.
- **Non-France purchase** (Belgique, Suisse, Luxembourg) — do not trigger; HCSF rules don't apply.

Full list (joint borrowers, profile-slug collisions, foreign currency income, TNS / self-employed flow): see `references/edge-cases.md`.

## Important rules (do not skip)

- **No financial advice** — estimate capacity, never recommend a duration, bank, or whether to buy.
- **No hardcoded rates or rules** — every regulatory number (35%, 25 ans, 20%) and every rate comes from Phase 2 WebFetch.
- **No HTML output** — markdown only.
- **Round to the nearest euro** in display; keep raw precision in the script JSON.
- **Joint borrowers**: sum incomes, sum debts at 100% for résidence principale.
- **DTI includes insurance** — the 35% cap is assurance comprise; the script handles this.

## Reference files

- `references/inputs.md` — Phase 1 input modes, parser commands, profile decisions, what to persist.
- `references/sources.md` — Authoritative URLs, fallback values, extraction prompts.
- `references/output-template.md` — Exact FR markdown structure for the briefing.
- `references/profile-schema.md` — JSON schema for `~/.francais-skills/profiles/{slug}.json` and privacy rules.
- `scripts/compute_capacity.py` — Deterministic capacity solver. Returns JSON.
- `scripts/profile_store.py` — Profile CRUD: list / show / save / delete / field.
- `scripts/parse_bulletin.py`, `parse_amortissement.py`, `parse_avis_impot.py` — PDF → JSON parsers (markitdown-based).

This indirection keeps the agent's context budget small — SKILL.md stays scannable, and references are pulled only on demand.

## Privacy & PII

Profiles store personal data (employer, salary, capital, RFR) under `~/.francais-skills/` (dir 0700, files 0600). **Never** put profile contents in commit messages, git diffs, web-pasted output, or telemetry. When the user shares a profile with a courtier, redact employer name, numéro fiscal, and account numbers first. See `references/profile-schema.md` for the full privacy rules.

## Examples (for triggering, not training)

- "Mon couple gagne 5500 net, on a 60k d'apport, on cherche un appart ancien — combien on peut emprunter ?" → triggers.
- "Capacité d'emprunt sur 25 ans avec 3800 € de revenus et un crédit voiture de 320 €/mois" → triggers.
- "Quel est le meilleur courtier ?" → does NOT trigger (recommendation, not estimation).
- "Combien je paie d'impôts si j'achète un appart en LMNP ?" → does NOT trigger (fiscalité).

