← 返回 Skills 市场
fredj

Vaudtax

作者 fredj · GitHub ↗ · v1.0.0 · MIT-0
cross-platform ✓ 安全检测通过
34
总下载
0
收藏
0
当前安装
1
版本数
在 OpenClaw 中安装
/install vaudtax
功能描述
Working with .vaudtax files (Swiss canton Vaud tax declarations). Use when the user mentions a .vaudtax file, wants to read/summarize/convert a VD tax declar...
使用说明 (SKILL.md)

VaudTax Skill

File format

A .vaudtax file is a ZIP archive containing:

  • One XML file (named \x3Cfilename>.xml) — the entire tax declaration as structured XML under the namespace http://www.vd.ch/fiscalite/vaudtax, root element \x3CvaudTaxData>.
    • Namespace: http://www.vd.ch/fiscalite/vaudtax (proprietary format, no public XSD available)
    • Structure: 32+ main sections organizing all tax declaration data
  • Zero or more doc* files — attached supporting documents: PDF, JPEG, or PNG. The format is declared in the XML's \x3CmimeType> field.

Bundled scripts

All scripts live in the scripts/ subdirectory of this skill and use only Python standard library — no installs needed.

Script Purpose
parse_vaudtax.py \x3Cfile.vaudtax> Parse and print a human-readable summary to stdout
export_json.py \x3Cfile.vaudtax> [out.json] Export clean JSON (omits UI/navigation state)
compute_code800.py \x3Cfile.vaudtax> Estimate revenu imposable ICC (code 800), IFD, and fortune — outputs values ready to pass to calculate_taxes.py
calculate_taxes.py --periode YEAR --commune NAME --revenu-icc N --fortune-icc N --revenu-ifd N Query the official Canton Vaud tax calculator via HTTP POST and return authoritative results

The JSON output conforms to vaudtax-export.schema.json (JSON Schema 2020-12; file is in the skill root).

SCRIPTS=$(find ~ -name parse_vaudtax.py -path '*/vaudtax/*' 2>/dev/null | head -1 | xargs dirname)
python "$SCRIPTS/parse_vaudtax.py" /path/to/file.vaudtax
python "$SCRIPTS/export_json.py"   /path/to/file.vaudtax

Key XML sections

Metadata & Taxpayer Info

Section Description
fiscalPeriod ✅ Tax year (e.g. 2025)
lastGesdemReference ✅ Gesdem submission reference
identification ✅ Address, municipality, phone, email, IBAN
taxpayerPersonalData1 ✅ Name, birthdate, NAVS13, profession, marital status
taxpayerPersonalData2 ✅ Second taxpayer (joint filers only)
representative Tax representative details (not yet parsed)

Income

Section Description
activiteSalarieeRevenus ✅ Employed income: employer, net salary, pension contributions, dates, activity rate
complementRentePension ✅ Pension/rente income: type, annual amount
activitesIndependantes ✅ Self-employment income: activity name, net revenue
autresRevenusExoneresImposesSource Other income (not yet parsed)
revenuImposeAutreEtat Income taxed in other states (not yet parsed)

Deductions & Expenses

Section Description
autresFraisEtFraisActiviteSalarialeAccessoire ✅ Professional expense deduction method (flat-rate or actual)
fraisTransport ✅ Transport costs: type, km, number of days, route
fraisRepas ✅ Meal costs: type, number of days
primesEtCotisationsAssurance ✅ Insurance premiums, subsidies, 3rd pillar (3a) contributions
deductionSocialeLogement ✅ Rent/housing deduction
fraisMedicauxDentaires ✅ Medical and dental expenses
interetsDettes ✅ Debt interest deductions (code 520)
fraisFormation ✅ Training/education costs
donationsAvancesHoiries ✅ Donations and inheritance advances
successionHoirieDonation Inheritances flag (skipped when isInitialized=false)

Assets & Securities

Section Description
etatTitres ✅ Bank accounts: IBAN, balance, yield
relevesFiscauxBancaires ✅ Investment portfolios: fiscal value, gross income, IES
numerairesList ✅ Cash and liquid assets
objetsMobiliers ✅ Movable property / crypto
biensImmobiliers (2025) / immeubles (older) ✅ Real estate: commune, parcelle, fiscal value, rental income
autoMoto ✅ Vehicles
fraisAdministrationTitres ✅ Management fees for securities (code 490)

Supporting Documents & Navigation

Section Description
piecesJustificativesObligatoires Mandatory supporting document metadata
piecesJustificativesFacultatives Optional supporting document metadata
infosComplementairesIes Additional investment income (IES) information
prestationsEnCapital Capital benefit payments (not yet parsed)
guidedNav / userProfil / piecesJustificativesSubFormInitialized UI/navigation state — intentionally skipped

Summarizing a file

Run parse_vaudtax.py and present the output using this structure:

  1. Filing info — fiscal year, reference, municipality
  2. Taxpayer(s) — name, birthdate, civil status, profession; CTB2 if joint filer
  3. Income — employed activity, pension/rentes, self-employment
  4. Deductions — transport, meals, professional expenses, insurance/3rd pillar, rent, medical, debt interest, education
  5. Assets — bank accounts, investment portfolios, cash, real estate, vehicles, movable objects
  6. Attached documents — filename and size for each
  7. Cross-check results — outcome of proactive PDF verification (see below)

Amounts are in CHF unless a different devise is specified.

Only report what exists. Do not mention sections that are empty, not initialized, or not applicable to this taxpayer. If parse_vaudtax.py reports no unknown sections, say nothing about sections at all.

A summary is just a summary. Do not run compute_code800.py or calculate_taxes.py unless the user explicitly asks for a tax estimate.

Proactive cross-checks

Even for a basic summary, always cross-check attached documents against their XML values — discrepancies are high-value findings the user needs before filing. Run all PDF reads in parallel (spawn one sub-agent per document or issue all open_attachment + read_pdf calls in a single parallel batch).

Pillar 3a attestations (label contains "21 EDP", "cotisations", or "pilier 3a"):

  1. Read each PDF with read_pdf() + extract_form21_totals() (or extract_postfinance_3a() for PostFinance) — see references/pillar-attestation.md
  2. Sum per taxpayer; compare against formesReconnuesPrevoyanceIndividuelleContribuable1 / ...Contribuable2
  3. Flag any discrepancy: "⚠ Écart pilier 3a : attestations CHF X, déclaration CHF Y — vérifier avant envoi"

Salary certificates (label contains "Certificat de salaire"):

  1. Read the PDF and extract line 11 (salaire net) and line 10.1 (LPP) — see references/salary-certificate.md
  2. Compare against salaireNet and cotisationOrdinaire in the XML
  3. Flag any mismatch beyond ±1 CHF rounding

Skip the cross-checks only if the user explicitly asks for a quick overview.

When verifying deductions, see references/deductions.md for official rules and caps.

Full analysis — always include taux marginal

For any full analysis (running both compute_code800.py and calculate_taxes.py), always also compute the taux marginal with --marginal-rate:

python calculate_taxes.py \
  --periode YEAR --commune "Commune" \
  --revenu-icc N --fortune-icc N --revenu-ifd N \
  --marginal-rate

This makes two HTTP calls and returns the marginal rate for ICC, IFD, and the combined total. Include it in the output:

Taux marginal
ICC (cantonal + communal) X.XX %
IFD (fédéral direct) X.XX %
Total X.XX %

See references/tax-computation.md for ICC and IFD formulas.

Reading attached PDFs

Use the bundled pdf_utils.py (in the skill's scripts/ directory):

from pdf_utils import read_pdf, extract_form21_totals, identify_taxpayer

text = read_pdf("/tmp/doc.pdf")               # text PDF or scanned — handled automatically
text = read_pdf("/tmp/doc.pdf", lang="deu")   # switch to German if needed

read_pdf() tries pdfplumber first; falls back to pytesseract OCR at 200 dpi. Use lang="fra" (default) for French, "deu" for German.

Read multiple attachments in parallel — spawn one sub-agent per document or issue all open_attachment + read_pdf calls concurrently. Wall-clock time scales with the slowest single document, not the total count.

For salary certificate field layout → references/salary-certificate.md For Form 21 EDP pillar attestation structure → references/pillar-attestation.md

Extracting attached files

Always use the open_attachment() context manager from parse_vaudtax.py — it extracts to a temp file and deletes it on exit:

from parse_vaudtax import open_attachment
from pdf_utils import read_pdf

with open_attachment("file.vaudtax", "doc17700000000000", suffix=".pdf") as path:
    text = read_pdf(path)

Use the \x3Ckey> value (not the \x3Creference> UUID) to match XML metadata to ZIP entries. Each \x3Cdocuments> element has: \x3Ckey>, \x3Cfilename>, \x3CmimeType>, \x3Clabel>, \x3CfileSize>.

VaudTax XML Schema

Proprietary format maintained by the Canton Vaud tax authority — no public XSD. Element names follow French naming conventions and may change across fiscal years.

Known differences between fiscal years

Section 2023–2024 2025
Medical expenses fraisMedicaux fraisMedicauxDentaires
Medical net amount montantACharge montantFrais
Real estate section immeubles biensImmobiliers
Real estate fiscal value valeurFiscale estimationFiscale

parse_vaudtax.py handles both variants transparently.

If a parsed field returns None unexpectedly, inspect actual child element names:

import zipfile, xml.etree.ElementTree as ET
NS = "http://www.vd.ch/fiscalite/vaudtax"
with zipfile.ZipFile("file.vaudtax") as z:
    xml_name = next(n for n in z.namelist() if n.endswith(".xml"))
    root = ET.parse(z.open(xml_name)).getroot()
for el in root.findall(f"{{{NS}}}sectionName"):
    print({c.tag.split("}")[1]: c.text for c in el})

Official references

Resource URL Notes
Instructions générales 2025 21001_2025.pdf Main guide; URL is year-specific
ICC barème revenu 2025 barème_revenu_2025.pdf Income tax table at CHF 100 intervals
ICC barème fortune 2025 barème_fortune_2025.pdf Wealth tax table at CHF 1'000 intervals
IFD barème 2025 (form 58c) Bareme_IFD_58c-2025.pdf Single + married tables
Communal coefficients Arrêtés d'imposition Current year XLS for all communes

Update PDF URLs by replacing the year suffix (e.g. 21001_2024.pdf for fiscal year 2024).

Reporting unhandled content

When the file contains sections or fields the skill can't handle, tell the user and suggest opening a GitHub issue.

Report when:

  • parse_vaudtax.py outputs a "Sections non reconnues" block
  • A section marked "not yet parsed" above contains data (isInitialized is not false and child elements are non-empty)
  • A script raises an exception or produces clearly wrong output

Say:

This declaration contains content the vaudtax skill doesn't handle yet: [describe what's missing]. The analysis above may be incomplete.

Please open an issue at https://github.com/fredj/ai-stuff/issues with: the fiscal year, the section name(s), and a brief description (no personal data needed).

Do not silently skip unhandled content.

Guardrails

Tax data is sensitive — being wrong is worse than being incomplete.

Sources — Every number must trace back to script output or a direct XML field read. Never supply a value from general knowledge. If a field is absent, say so — absent ≠ zero ≠ "not applicable".

No mental arithmetic — Never compute ICC/IFD/fortune tax without running compute_code800.py + calculate_taxes.py. The only exception is explaining the method conceptually.

Year-specific rules — Always read fiscalPeriod before applying any deduction cap, barème table, or form field name. The limits in references/deductions.md are 2025 values and differ for other years.

No guessing — Never infer what an unhandled section contains, never fabricate totals from partial data, never guess XML field names (use the discovery snippet above).

Estimates vs official figurescompute_code800.py output is an estimate. When a lastGesdemReference or official bordereau is available, those figures take precedence.

Commune rates — Tax coefficients are commune-specific. Flag any mismatch between the commune in identification and the one passed to calculate_taxes.py.

Réforme valeur locative (from 2029) — Valeur locative suppressed, mortgage interest non-deductible (except primo-acquéreurs Art. 33a LIFD), code 660 disappears for IFD. Do not apply pre-2029 rules to post-2028 projections.

Network — The only network call is calculate_taxes.pyhttps://www.vd.ch/.... It sends three integers, the commune name, and marital status — no personal identifiers.

When in doubt: say what you found, say what you couldn't find, and let the user decide.

安全使用建议
Install only if you are comfortable letting an agent read sensitive Vaud tax declarations and attachments. Basic parsing and summaries can be kept local; tax-estimate/full-analysis mode sends taxable income, taxable wealth, commune, marital status, and child-count data to the official vd.ch calculator. Ask for a quick overview or local-only analysis if you do not want attachment OCR or remote calculation.
能力标签
crypto
能力评估
Purpose & Capability
The artifacts consistently support reading .vaudtax ZIP/XML files, summarizing sensitive tax data, extracting attachments, OCR/PDF cross-checks, JSON export, local tax-base estimation, and an official Vaud tax-calculator query. These capabilities fit the stated tax-analysis purpose, though they handle highly sensitive personal and financial data.
Instruction Scope
The skill tells the agent not to run tax computation or the remote calculator for a basic summary unless the user asks for a tax estimate, and it discloses proactive PDF cross-checking unless the user requests a quick overview. The remote calculation path would benefit from an explicit runtime confirmation, but it is not hidden in the artifact instructions.
Install Mechanism
There are no install hooks, package installers, startup changes, or obfuscated setup behavior. One documentation inconsistency is that the skill says scripts use only the Python standard library, while pdf_utils.py imports pdfplumber, pytesseract, pdf2image, and PIL; this is a reliability/disclosure issue rather than malicious behavior.
Credentials
Temporary attachment extraction, local parsing, optional JSON output, and a fixed HTTPS POST to vd.ch are proportionate to the declared workflow. The network call sends tax-derived fields such as taxable income, wealth, commune, marital status, and child counts, so users should treat tax-estimate mode as non-local processing.
Persistence & Privilege
No persistence, privilege escalation, credential access, background service, broad indexing, or destructive behavior was found. Attachment temp files are deleted by the context manager, and JSON export writes only when the export script is invoked.
如何使用
  1. 确保已安装 OpenClaw(本地或 Docker 部署)
  2. 在对话框中输入安装命令:/install vaudtax
  3. 安装完成后,直接呼叫该 Skill 的名称或使用 /vaudtax 触发
  4. 根据 Skill 的参数说明提供必要输入,即可获得结构化输出
版本历史
v1.0.0
VaudTax Skill 1.0.0 — Initial release for working with Swiss Canton Vaud tax declarations. - Supports reading and summarizing .vaudtax files (ZIP with XML and attachments). - Includes bundled Python scripts for parsing, JSON export, income/asset extraction, and authoritative tax calculations. - Summaries report only present data: filing info, taxpayer(s), income, deductions, assets, and attached documents. - Performs proactive cross-checks: verifies pillar 3a contributions and salary certificates by reading attached PDFs and comparing to declared amounts. - Exposes standard-structure JSON output (vaudtax-export.schema.json). - Designed for reliable extraction, summary, and verification without external dependencies.
元数据
Slug vaudtax
版本 1.0.0
许可证 MIT-0
累计安装 0
当前安装数 0
历史版本数 1
常见问题

Vaudtax 是什么?

Working with .vaudtax files (Swiss canton Vaud tax declarations). Use when the user mentions a .vaudtax file, wants to read/summarize/convert a VD tax declar... 它是一个面向 Claude Code / OpenClaw 的 AI Agent Skill 插件,目前累计下载 34 次。

如何安装 Vaudtax?

在 OpenClaw 或 Claude Code 对话框中运行命令「/install vaudtax」即可一键安装,无需额外配置。

Vaudtax 是免费的吗?

是的,Vaudtax 完全免费,采用 MIT-0 许可证,可自由下载、安装和使用。

Vaudtax 支持哪些平台?

Vaudtax 跨平台运行,可在任意部署了 OpenClaw / Claude Code 的环境中使用(cross-platform)。

谁开发了 Vaudtax?

由 fredj(@fredj)开发并维护,当前版本 v1.0.0。

💬 留言讨论