| name | appel-de-fonds |
| description | Analyze French syndic quarterly charge-call PDFs (appels de fonds), persist extracted charges as a local KB, and generate one beautiful anomaly-focused HTML report. Don't use for AG convocations, tax notices, bank statements, or non-copropriété PDFs. |
| metadata | {"version":"1.0.0","author":"francais-skills"} |
appel-de-fonds — Quarterly copropriété charge analyzer
Analyze one or more French syndic appels de fonds / avis d'échéance / répartitions de charges PDFs, persist the extracted data as a reusable local knowledge base, and generate a single polished HTML report that highlights important charges and abnormal items.
Repo Sync Before Edits (mandatory)
Before writing or modifying files inside a git repository, sync the current branch so generated reports or KB exports do not clobber newer work:
branch="$(git rev-parse --abbrev-ref HEAD)"
git fetch origin
git pull --rebase origin "$branch"
If the working tree is dirty, stash first, sync, then pop. If origin is missing or the rebase/pop has conflicts, stop and ask the user before continuing. If writing only to the default user KB under ~/.copro-charges-kb/, this repo-sync step is not needed.
When this skill triggers
Use this skill when the user provides French copropriété charge PDFs from a syndic, especially terms like appel de fonds, avis d'échéance, charges, trimestre, répartition, fonds travaux, syndic, copropriété, or asks to analyze quarterly residence charges.
Do not use it for AG convocations and resolutions (use ag-copro), income tax files (use declaration-impot-fr), mortgage capacity, generic bank statements, invoices unrelated to copropriété, or non-French residence charges.
Inputs
Accept any of these:
- A list of PDF paths.
- A directory containing PDFs, for example
appel-de-fonds/.
- Multiple residence folders; keep residence identities separate unless the user asks to merge.
The document template is variable. Never rely on fixed page coordinates or a single syndic layout. Anchor extraction on semantic labels and table headers.
Output files
Write one self-contained HTML report to the current working directory:
./charges-<residence-slug>-<period-range>.html
Also persist structured extraction data to the local KB:
~/.copro-charges-kb/<residence-slug>/charges.jsonl
~/.copro-charges-kb/<residence-slug>/documents/<document-id>.json
~/.copro-charges-kb/<residence-slug>/latest-report.json
The HTML embeds the final dataset as JSON in <script type="application/json" id="charges-data">…</script> so future Q&A can use the report even if the KB is unavailable.
Workflow
Phase 1 — Intake and environment
- Resolve all PDF paths to absolute paths.
- If the user gave a folder, recursively include
*.pdf files and ignore hidden/system files.
- Check whether
docling is available: python -c "import docling".
- If missing, ask before installing. Prefer the current virtualenv; otherwise suggest
python -m pip install docling.
- Create a run workspace under
~/.copro-charges-kb/_runs/<timestamp>/ for extracted markdown, tables, logs, and intermediate JSON.
After this phase, output a Step Completion Report.
Phase 2 — Extract every PDF with Docling
Use Docling as the primary extractor because syndic PDFs can mix text blocks, tables, scans, and inconsistent layouts.
For each PDF:
- Run Docling conversion to Markdown/JSON when possible.
- Preserve page numbers, table boundaries, and raw text snippets for citations.
- If Docling fails or returns too little text, fall back to OCR-capable PDF tools if available, and clearly mark lower confidence.
- Extract document metadata:
- residence / copropriété name and address
- syndic name
- copropriétaire name or account reference if present
- document type (
appel_de_fonds, regularisation, travaux, taxe, other_copro_charge)
- period start/end, quarter, due date, issue date
- total due, previous balance, payments/credits, net amount payable
- Extract all charge lines from tables:
- label as printed
- normalized category
- amount called for the owner
- building/residence total when present
- tantièmes / clé / lot reference when present
- VAT/tax if present
- page and source snippet
Use references/extraction.md for field definitions, landmarks, and normalization rules.
Phase 3 — Persist the knowledge base
Read references/knowledge-base.md before writing KB files.
- Generate a stable
document_id from residence, period, source filename, and total amount.
- Append one JSONL record per charge line to
charges.jsonl unless an identical source_hash + line_hash already exists.
- Save one full document JSON under
documents/<document-id>.json.
- Update
latest-report.json with the report dataset and anomaly summary.
- Keep original source paths and hashes; do not copy PDFs into the KB unless the user asks.
Phase 4 — Detect abnormal items
Compare within the current batch and against historical KB records for the same residence:
- Quarter-over-quarter and year-over-year changes by normalized category.
- New labels/categories never seen before.
- Large one-off works or tax/insurance lines.
- Duplicate calls for the same period/category.
- Negative credits, unexplained balances, or payment deadlines already passed.
- Owner share that appears inconsistent with tantièmes or previous periods.
Flag anomalies by severity: info, watch, warning, critical. Never accuse the syndic of an error; phrase as "à vérifier" unless the document itself proves the issue.
Phase 5 — Generate the HTML report
Use the frontend-design skill's production-grade UI principles if available: distinctive but readable design, responsive layout, clear hierarchy, accessible contrast, no generic dashboard slop.
Read references/html-report.md for the required sections and visual style. The report must include:
- Executive summary cards: amount due, period, due date, biggest category, anomaly count.
- Timeline of quarters/documents.
- Category breakdown chart and per-quarter comparison chart (Chart.js via CDN is acceptable).
- Table of all charge lines with filters and severity badges.
- "Abnormal / à vérifier" section explaining each flagged item with evidence.
- Knowledge-base status: records added, duplicates skipped, KB path.
- Embedded JSON source data for follow-up questions.
Write a single .html file. If the target exists, ask before overwriting.
Phase 6 — Review and answer
Before presenting the result, do a quick consistency review:
- Sum of extracted line amounts vs document totals.
- Period labels are plausible quarters.
- Every anomaly has a source page/snippet.
- HTML contains the embedded
charges-data JSON.
- KB files were written or a clear reason is reported.
Then summarize the important points in 3–6 bullets and provide the report path.
Subagent architecture
If the Agent tool is available, keep the main agent as orchestrator:
- For 3+ PDFs, spawn parallel worker subagents using
agents/pdf-worker.md, one worker per PDF or small batch.
- Spawn one synthesis/report subagent using
agents/report-builder.md to merge worker JSON, update the KB, and write the HTML.
- Spawn a fresh reviewer subagent using
agents/reviewer.md for independent quality checks.
If Agent is not available, execute the same phases inline.
Query mode
If the user asks a follow-up question after a report exists:
- Prefer the HTML's embedded
charges-data JSON if a report path is provided.
- Otherwise load the residence KB from
~/.copro-charges-kb/.
- Answer from stored data only. If the answer requires re-reading PDFs, say so and ask whether to re-extract.
- Keep French copropriété terms in French (
appel de fonds, tantièmes, fonds travaux, régularisation).
Step Completion Reports
After each major phase, output this compact report, adapting check names to the phase:
◆ [Phase Name] ([step N of 6] — appel-de-fonds)
··································································
PDFs resolved: √ [count]
Docling extraction: √ [count ok] / [count total]
KB persistence: √ [records added], [duplicates skipped]
Anomaly scan: √ [count] flagged
HTML report: √ ./charges-[slug]-[range].html
Criteria: √ [N/M] met
____________________________
Result: PASS | PARTIAL | FAIL
Constraints
- Do not invent missing amounts. Store
null and lower confidence when a field cannot be extracted.
- Keep page/source snippets for every important number and anomaly.
- Do not provide legal advice or accuse fraud. Explain what the document says and what the user may want to verify with the syndic/conseil syndical.
- Treat personal data as sensitive. Do not upload PDFs or KB contents to external services unless the user explicitly asks.
- Prefer local persistent storage under
~/.copro-charges-kb/ so knowledge survives across projects without polluting repos.
Reference files
references/extraction.md — Docling extraction strategy, landmarks, schema, and category normalization.
references/knowledge-base.md — persistent KB layout, deduplication, and query rules.
references/html-report.md — required report sections, visual design, embedded JSON contract.
agents/pdf-worker.md — prompt for parallel per-PDF extraction workers.
agents/report-builder.md — prompt for synthesis, KB update, and HTML generation.
agents/reviewer.md — prompt for independent quality review.