| name | quarterly-close |
| description | Run the QuarterlyAssistant quarter-close pipeline and review the results. Use whenever the user wants to "close the quarter", "run the pipeline", "do the Modelo 130", "calculate the trimestre", asks "what do I owe this quarter", wants the libros/books generated, or asks to process the bank statements and receipts they've dropped in — also for re-runs after answering questions or adding late receipts. Requires the QuarterlyAssistant folder to be connected. |
Quarter close — QuarterlyAssistant
Run the deterministic pipeline (AGENTS.md §4, Stages 1–7) and walk the user through what came out. The pipeline is idempotent — re-running is always safe and is the normal way to incorporate answers and late documents.
Orientation
Repo = connected folder with AGENTS.md and tools/pipeline.py. Tenant = folder under tenants/ (ask if several). Deps once per session: pip install --break-system-packages pyyaml openpyxl weasyprint jinja2 (plus pdftotext from poppler, usually present).
Workflow
-
Determine the quarter (current one unless stated). If not scaffolded:
python3 tools/pipeline.py init-quarter <tenant> <YYYY-Qn>
-
Check inputs before running. Anything in accounts-incoming/ and receipts-incoming/? If the user expects statements/receipts to be processed but the folders are empty, say so — an empty run produces empty books, which looks like a bug to the user. Bank accounts in config.yaml need format: set (generic_csv + column mapping, n26_csv, sparkasse_csv); if a statement file fails to parse, inspect its header and either configure generic_csv columns or flag that a new parser is needed.
-
Run: python3 tools/pipeline.py run <tenant> <YYYY-Qn>
The 130 is cumulative — earlier quarters of the year must have been built; the pipeline errors clearly if not (build them first).
-
Triage the outputs, in this order:
build/questions.md — open questions block correct numbers. Resolve them with the user (batched, AskUserQuestion), write the answers as rules into memory/rules.yaml (existing entry format), re-run from classify. Never leave a question answered only in chat — memory is what prevents re-asking.
build/exceptions.md — missing receipts (the user's main to-do; these are currently NOT deducted — say what that costs, roughly 20% of the expense), unpaid issued invoices, ambiguous matches.
- Stage 7 failures — the modelo-130 report gets renamed
.BLOCKED.md; fix the cause, never hand-edit outputs.
-
Present the results: the build/modelo-130-<Q>.md casilla table (this is what the user types into Renta Web), the libros .xlsx, and the one-line bottom line ("casilla 19: X € a ingresar, deadline …"). Present files with present_files.
Judgment calls
- Numbers change when questions are answered or receipts added — always re-run rather than patching JSON by hand; everything under
build/ is regenerable and must never be edited manually.
- If income is near the REPEP threshold (50.000 € since 2026-07, Decreto ley 3/2026) or retenciones covered ≥ 70 % of prior-year income, surface the flag — these change the tenant's obligations (AGENTS.md §9.6, §10).
- Tax constants live in
tools/qa/constants.py with sources. At the first close of a new fiscal year, verify them against current AEAT/ATC forms before trusting the output (hard rule 6) — web-search if needed.