# Declaration Impot Fr

> 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.

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

---


# 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 <slug>" / "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

- `python3` on PATH.
- `markitdown` **with the PDF extra** only for PDF parsing (Mode B): `pip install "markitdown[pdf]"` (or `markitdown[all]`). A bare `markitdown` install raises `MissingDependencyException` on PDFs. Interactive/profile mode works without it. See `requirements.txt`.
- WebFetch access to Service-Public (`service-public.gouv.fr` when available, otherwise canonical `service-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 with `Source au YYYY-MM-DD`.
- Never compute tax inline. Always run `scripts/compute_ir.py` and 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:

```bash
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`):

```bash
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:

```text
◆ 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-DD` line appears for every regulatory figure used.
- `scripts/compute_ir.py` was 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`:

```markdown
## 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, expected `regulatory.json` shape.
- `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.

