name: declaration-impot-fr description: "Prepare French 2025 income-tax declaration filed in 2026: collect inputs/PDFs/profiles, fetch official rules, compute IR, render markdown. Don't use for tax optimization, filing/submission, non-France tax, or impots.gouv.fr login." license: MIT metadata: version: "1.0.0" author: "francais-skills" effort: high
declaration-impot-fr — Déclaration IR 2025 (France, dépôt 2026)
Help a French tax resident prepare the figures and checks needed for the 2025 income-tax declaration filed in 2026. The skill collects data, fetches current official tax rules, runs the deterministic IR calculator, and renders a French markdown briefing. It never files anything.
When to use
- "Aide-moi à préparer ma déclaration d'impôt 2025" / "déclaration revenus 2025".
- "Combien d'impôt vais-je payer avec mes salaires, PER, dividendes ?"
- "Voici mon bulletin / attestation France Travail / attestation PER / IFU dividendes / avis d'impôt N-1".
- "Charge mon profil impôts
" / "sauve ce profil fiscal". - The user invokes
/declaration-impot-fr.
Do not use for: filing/submitting on impots.gouv.fr, FranceConnect or impots.gouv.fr login help, credential storage, tax optimization recommendations without comparative numbers, business tax, wealth tax/IFI-only questions, non-French tax returns, or legal/accounting advice.
Output: one French markdown briefing
Render inline markdown only. Use references/output-template.md and keep the final line exactly:
Ce calcul est indicatif. Seul l'avis d'imposition de la DGFiP fait foi.
The briefing must include: user inputs, official sources with Source au YYYY-MM-DD, computed JSON highlights, points to verify manually, and neutral comparisons when the user asks about optional choices.
Prerequisites
python3on PATH.markitdownwith the PDF extra only for PDF parsing (Mode B):pip install "markitdown[pdf]"(ormarkitdown[all]). A baremarkitdowninstall raisesMissingDependencyExceptionon PDFs. Interactive/profile mode works without it. Seerequirements.txt.- WebFetch access to Service-Public (
service-public.gouv.frwhen available, otherwise canonicalservice-public.fr) and official linked sources (impots.gouv.fr,legifrance.gouv.fr). If official sources cannot be fetched, stop before computing rather than using stale hardcoded tax figures. - Write access to
~/.francais-skills/profiles/for optional profile storage. Profiles are private local JSON files (0700 dirs, 0600 files).
Non-negotiable safety rules
- Never submit a declaration, click through impots.gouv.fr, log in, use FranceConnect, ask for passwords, store credentials, or persist fiscal login identifiers.
- Never hardcode regulatory amounts in the briefing or in
SKILL.md. Fetch official values at runtime and cite them withSource au YYYY-MM-DD. - Never compute tax inline. Always run
scripts/compute_ir.pyand render its JSON. - Never recommend an option as "best" unless you show comparative computed numbers for each option and let the user decide.
- Never publish or commit profile contents, PDF text, fiscal identifiers, or generated personal tax data.
Workflow
Follow phases in order and emit a short status after each major phase.
Phase 0 — Scope and profile
Confirm the task is a French resident income-tax preparation for 2025 revenues filed in 2026. Then decide profile mode with scripts/profile_store.py:
- load-profile request:
python3 scripts/profile_store.py show <slug>; - save-profile request: remember the slug for Phase 6;
- no profile mentioned: list profiles once and ask in one batch whether to load one or continue without.
Read references/profile-schema.md before saving or updating a profile.
Phase 1 — Collect inputs
Use one of the three modes in references/inputs.md:
A. Interactive — ask all missing questions in one AskUserQuestion batch.
B. PDFs — run the matching parser for each attached document, then confirm extracted figures before computing. Parsers do not tag declarant; when one person has several salary/chômage lines (multiple employers, or salary + chômage), add the same declarant value to those lines so the per-person 10% floor/ceiling is applied correctly (see references/inputs.md). If compute_ir.py returns a manual_review note about untagged lines, tag them and recompute.
C. Load profile — use the loaded private profile, only asking for explicit updates.
Phase 2 — Fetch official rules (mandatory)
Read references/sources.md, then WebFetch official sources on every invocation. Build a regulatory.json object containing at least brackets, quotient familial cap data, décote parameters, abatement parameters, PER rules needed for the user's inputs, and source metadata.
Every regulatory number that appears in the briefing must come from this fetched object. If a source is unreachable and no official alternative is available, report the blocker and stop.
Phase 3 — Compute deterministically
Create an input JSON from Phase 1 and run:
python3 scripts/compute_ir.py --input inputs.json --regulatory regulatory.json
When the inputs come from a saved profile, generate them with the transform
rather than feeding the profile directly — a raw profile deductions block can
double-count an aggregate (per) against its breakdown (per_luong, per_mai):
python3 scripts/profile_store.py to-inputs <slug> > inputs.json
The deductions object must contain only canonical leaf amounts (per,
pension_alimentaire_ascendants, pension_alimentaire_enfants,
autres_charges_deductibles); see references/inputs.md.
The script returns JSON with the required tax fields. If it exits non-zero, show stderr and fix the input/source JSON; do not patch numbers by hand.
Phase 4 — Render
Render references/output-template.md from the compute JSON and fetched source metadata. Do not add extra arithmetic. Do not cite a rule without a Source au YYYY-MM-DD line.
Phase 5 — Compare optional choices only when asked
For choices such as PER deduction amount, PFU vs barème on dividends, or frais réels vs forfait, run separate compute inputs for each option and show a comparison table. Do not choose for the user.
Phase 6 — Persist profile if requested
Save only durable user inputs and document provenance via scripts/profile_store.py save <slug>. Do not persist fetched regulatory data, generated briefings, credentials, passwords, FranceConnect data, impots.gouv.fr session data, or fiscal identifiers.
Phase 7 — Status report
End with this block:
◆ Déclaration impôt FR (terminé)
··································································
Profil: √ chargé (<slug>) / √ nouveau / — non utilisé
Inputs collectés: √ pass (mode A interactif / B PDFs / C profil)
Sources officielles: √ pass (Source au YYYY-MM-DD) / × bloqué
Calcul script: √ pass
Briefing rendu: √ pass
Profil sauvé: √ pass (<slug>) / — non sauvé
Sécurité: √ aucun login, aucune soumission, aucun credential
____________________________
Result: PASS
If official sources could not be fetched, mark Sources officielles: × bloqué, skip calculation, and set Result: PARTIAL.
Acceptance Criteria
- The output is French markdown, not HTML.
- A
Source au YYYY-MM-DDline appears for every regulatory figure used. scripts/compute_ir.pywas invoked; no inline arithmetic was used.- The briefing includes these script JSON fields: revenu net imposable par catégorie, RFR, parts, impôt brut, décote, impôt net, taux marginal, taux moyen.
- The briefing contains the exact DGFiP disclaimer as the final line.
- PDF-extracted values were confirmed before use.
- Profiles stay under
~/.francais-skills/, with no credentials or fiscal login identifiers. - Optional choices are shown as comparative numbers, never as a recommendation.
Expected output
Shape only; numbers come from fetched official rules and compute_ir.py:
## Préparation déclaration d'impôt 2025 — synthèse
### Vos données retenues
- Foyer fiscal, parts, catégories de revenus, déductions, réductions/crédits.
### Sources officielles utilisées
> Source au YYYY-MM-DD: Service-Public + sources officielles liées (...).
### Résultat indicatif du calcul
| Indicateur | Montant / taux |
| --- | ---: |
| Revenu fiscal de référence estimé | ... € |
| Impôt net après réductions/crédits | ... € |
| Taux marginal | ... % |
### Points de saisie à contrôler sur impots.gouv.fr
- ...
Ce calcul est indicatif. Seul l'avis d'imposition de la DGFiP fait foi.
Edge cases
- Official sources unavailable: stop before calculation; do not use remembered values.
- Complex parts, foreign income, non-resident period, actual-regime business income, or PER carry-forward: mark manual review.
- Login/submission request: refuse credential handling and offer an offline checklist instead.
- Parser uncertainty: ask the user to confirm the raw figure before computing.
- Optional choice request: run separate compute scenarios and show a neutral comparison table.
Reference files
references/sources.md— official URLs, extraction prompts, expectedregulatory.jsonshape.references/inputs.md— interactive questions, PDF parser commands, merge rules.references/profile-schema.md— private profile schema and privacy rules.references/output-template.md— exact French markdown skeleton.references/edge-cases.md— manual-review, no-submit, and comparison behavior.scripts/compute_ir.py— deterministic IR calculator, JSON in/out.scripts/profile_store.py— private profile CRUD.scripts/parse_*.py— markitdown-style PDF parsers.