The Regulation Development Problem
A country payroll regulation is a dense artifact. It encodes the statutory rules for income tax withholding, social security contributions, employer obligations, electronic filing, and dozens of edge cases — all expressed as structured JSON, C# scripts, lookup tables, and integration tests.
The German regulation (DE.Entgeltabrechnung) took the better part of a year to reach its current state. It includes the PAP algorithm, Solidaritätszuschlag, Kirchensteuer, five social security branches, Umlagen, Kurzarbeitergeld, §3b surcharges, garnishment, the Märzklausel, and three XML filing reports. Its test suite has over 50 integration tests.
The traditional regulation development process follows a sequential pattern:
- Research: Read the statutory sources (tax authority publications, official gazettes, legal texts). For Germany, that’s the BMF PAP, SV-RechengrößenV, various SGB provisions. For Australia, that’s ATO NAT 1004, NAT 3539, the STP specification.
- Model: Design the case fields, wage types, collectors, and data satellites. Decide on timeTypes, valueTypes, collector memberships, and cluster assignments.
- Implement: Write the JSON regulations, C# Custom Actions, lookup tables, and data regulation satellites.
- Test: Create integration tests with hand-calculated expected values. Verify against official examples where available.
- Report: Build PDF payslips, employer cost summaries, journals, and statutory filing reports (XML/electronic).
Each step requires domain expertise. The research phase requires reading legal texts in the country’s language. The modelling phase requires understanding PayrollEngine’s architecture. The implementation phase requires both. The testing phase requires hand-calculating expected values from statutory formulas.
This process is where AI changes the equation.
What AI Changes
The Australian regulation was built with AI-assisted development — an LLM (Claude) working inside the IDE with full access to the codebase, the PayrollEngine API documentation, existing country regulations as templates, and ATO statutory publications.
The development followed a phased approach:
| Phase | Scope | Output |
|---|---|---|
| Phase 0 — Scaffold | Repository structure, regulation shell, case definitions, empty wage types, test fixtures | 15 JSON files, 7 script stubs, CI/CD workflows |
| Phase 1 — Core | Data regulations (PAYG coefficients, Super, Medicare, PayrollTax), guard wage types, gross/tax/employer calculations | 4 data satellites populated, 7 Custom Actions, 5 passing tests |
| Phase 2 — Extensions | Working Holiday Makers, salary sacrifice, leave loading, retro corrections, AdapterImport | 14 passing tests, Docs folder (9 standard files) |
| Phase 2b — Prorata & Expansion | Prorata calculations, algorithm extraction, negative tests, unit tests, intramonth scenarios | 36 passing tests, 3 extracted algorithm classes |
| Phase 3 — Reports | Payslip, Employer Cost Summary, Payroll Journal, Tax Reconciliation, STP PayEvent XML | 5 reports (4 PDF + 1 XML) |
What the AI does well:
- Pattern replication. Given an existing country regulation (US.Payroll served as the primary template), the AI generates the scaffold for a new country by adapting the structure — renaming cases, adjusting wage type numbers, creating the correct data satellite shells.
- Statutory research. The AI reads ATO publications (NAT 1004, NAT 3539, SGC rate announcements) and extracts the coefficient tables, rate thresholds, and bracket boundaries into structured lookup JSON.
- Algorithm implementation. Given a specification (“weekly withholding = earnings × a − b, where a and b are looked up from the PAYG coefficient table for the employee’s tax scale”), the AI writes the C# Custom Action and the standalone algorithm class.
- Test generation. Given a scenario (“employee earning $7,500/month on Scale 2 with tax-free threshold”), the AI calculates the expected PAYG using the coefficient method and generates the integration test JSON with the correct expected values.
- Report scripts. Given the report pattern from other countries (DE LStAnmeldung for XML, NL Payslip for PDF), the AI writes the
ReportEndFunctionscripts that query payrun results and reshape them for the report template.
What AI Does Not Change
Speed is the visible change. But the invisible part is more important: the AI did not reduce the correctness requirements. Every number in the regulation still needs to be right.
Statutory verification is still manual
The AI can read ATO publications and extract coefficient tables. But the verification — confirming that the extracted values match the official source — requires a human checking the numbers against the gazette. A coefficient table with a transposed digit produces payslips that are wrong by a few dollars per employee per pay period. Multiply that across 200 employees and 12 months, and a single wrong coefficient creates a material compliance issue.
The compliance verification protocol is the same whether the regulation was built by hand or by AI:
- Identify every statutory value in the data regulation
- Verify each value against the official online source
- Produce a verification table (value, source URL, legal basis, status)
- Only then write the value into the regulation
AI accelerates the lookup. It does not replace the verification.
Architecture decisions require domain understanding
The AI can generate a wage type that calculates PAYG. But the decision to use the coefficient method rather than implementing progressive brackets directly — that requires understanding why the ATO publishes coefficients in the first place (they pre-compute the effective rate to simplify payroll software) and that the coefficient method is the compliance-standard approach.
Similarly, the decision to implement WT 7015 (employee social security) as a hard-coded zero for Australia rather than omitting it entirely — that requires understanding the consolidation interface’s semantic contract.
Edge cases need adversarial thinking
The prorata boundary tests (employee starts on the last day of the month, employee exits on the first day) were not generated spontaneously by the AI. They were prompted by experience with edge cases in other country regulations. The intramonth relocation test (NSW to VIC mid-month) was designed to verify that the engine’s time-splitting handles state payroll tax transitions correctly.
The AI generates the test mechanics efficiently. The decision about which edge cases to test comes from domain experience.
Lessons Learned
The AU regulation development surfaced several patterns that apply to AI-assisted regulation development generally:
1. Template quality determines output quality
The AI’s output quality is directly proportional to the quality of the template regulation it works from. The US regulation, with its clean scaffold, consistent naming, and comprehensive test coverage, produced a better starting point than an incomplete or inconsistently structured template would have.
This creates a virtuous cycle: each completed regulation raises the template quality for the next one.
2. Best practices must be codified, not assumed
The AI doesn’t “know” the best practices from prior regulation development unless they are written down in a place it can access. The namespace rule (never prefix object names with the country code inside a namespaced regulation), the test README format, the Custom Action header pattern, the mandatory braces rule — these were all discovered through errors in early iterations and then codified as explicit rules.
Every mistake the AI makes once becomes a documented rule that prevents the same mistake in every subsequent regulation.
3. Eligibility logic belongs in the wage type, not in the case
The most instructive bug in the AU development was discovered in Phase 1. The casual loading wage type (WT 1020) used availableActions to check whether the employee was casual. This works for UI visibility — it hides the field for non-casual employees. But availableActions does not gate the wage type’s value calculation. The wage type ran for all employees, adding a casual loading to full-time employees’ taxable income.
The fix is the same pattern used in the German regulation: pass the discriminator field into the Custom Action and return zero when the condition doesn’t match. This was already the established pattern in DE.Entgeltabrechnung but wasn’t surfaced prominently enough for the AI to apply it by default.
After this discovery, the rule was codified in the best practices: “availableActions controls Case UI availability only. Wage type eligibility must be enforced inside the valueActions or Custom Action.”
4. Algorithm extraction enables unit testing
The initial PAYG implementation embedded the coefficient lookup logic directly in the Custom Action. This works functionally, but it means the algorithm can only be tested through full payrun integration tests — which require a running backend, tenant setup, and employee fixtures.
Extracting the algorithm into a standalone class (PaygAlgorithm.cs, SfssAlgorithm.cs, WhmAlgorithm.cs) enables unit tests that run in milliseconds without any backend. The integration tests verify end-to-end correctness; the unit tests verify algorithmic correctness. Both are necessary.
5. Negative tests have cross-country conventions
The AU regulation initially used completedJobStatus: "Abort" for guard/negative tests — the intuitive choice when a guard calls AbortExecution. But this leaves the payrun job in Draft status, and PayrollEngine allows only one Draft job per payrun. All subsequent tests in the suite fail.
The correct convention (used in DE, NL, UK, US) is completedJobStatus: "Complete" with empty result arrays. The guard still prevents calculation for the individual employee, but the job completes normally. This convention exists because it was discovered empirically in earlier regulations — but it wasn’t documented prominently enough for the AI to discover on its own.
Anatomy of the Regulation
The completed AU regulation consists of:
| Component | Count | Details |
|---|---|---|
| Regulation JSON files | 15 | Cases (company + 7 employee), wage types (guard, gross, deductions, employer), collectors, scripts |
| Data regulation satellites | 4 | Tax (PAYG coefficients, STSL rates), Super, Medicare, PayrollTax |
| Custom Action scripts | 13 | Guard (3), Gross (4), Tax (4), Employer (2) |
| Algorithm classes | 3 | PaygAlgorithm, SfssAlgorithm, WhmAlgorithm |
| Integration tests | 36 | 27 WT-TC, 2 GUARD-TC, 2 CV-TC, 1 CONS-TC, 4 negative |
| Reports | 5 | Payslip, EmployerCostSummary, PayrollJournal, TaxReconciliation (PDF) + StpPayEvent (XML) |
| Case fields | ~40 | Personal data, employment, remuneration, tax, superannuation, banking, leave |
| Collectors | 6 | 3 collector groups (GrossBase, OteBase, TaxBase) |
This is comparable in scope to the UK regulation — not as complex as Germany (which has five social security branches, Kirchensteuer, and Kurzarbeitergeld), but structurally complete with all the components a production payroll needs.
The Role of AI in Regulation Development
The AI is not the payroll expert. The AI is a development accelerator that works within a structured framework:
| Task | Without AI | With AI |
|---|---|---|
| Scaffold a new country regulation | Copy template, rename manually, fix references | Generate from template with country-specific adaptations |
| Populate data satellite (coefficient table) | Read ATO PDF, type values manually | Extract from publication, generate JSON structure |
| Write Custom Action (PAYG calculation) | Implement from spec, debug, iterate | Generate from formula, review, test |
| Create integration test | Hand-calculate expected values, write JSON | Calculate from statutory formula, generate test JSON + README |
| Verify statutory values | Check official source manually | Check official source manually (unchanged) |
| Decide regulation architecture | Domain expert judgment | Domain expert judgment (unchanged) |
| Design edge case tests | Experience from prior regulations | Experience from prior regulations + AI generates mechanics |
The pattern is consistent: AI accelerates the mechanical work (generating JSON, writing C#, formatting test data) but does not replace the judgment work (verifying compliance, designing architecture, choosing edge cases).
This maps directly to PayrollEngine’s automation ladder:
- No-Code — payroll consultants define calculations with tokens
- Low-Code — developers write C# expressions
- Custom Actions — senior developers implement complex logic
- AI-assisted development — AI generates all of the above, humans verify and decide
Each level raises productivity. None of them remove the need for someone who understands payroll.
The Infrastructure That Makes It Possible
AI-assisted regulation development works because the underlying infrastructure is designed for it:
- Regulations are data, not code. Exchange JSON and YAML are structured, parseable, and diffable. The AI generates data artifacts that can be reviewed line by line, not compiled binaries.
- The framework provides the runtime. The AI doesn’t implement payrun logic, period handling, time-splitting, or result storage. Those are engine concerns. The regulation only needs to express what to calculate, not how to run a payroll.
- Integration tests are self-contained. A
.et.jsonfile contains everything needed to run a test — case data, payrun invocation, expected results. The AI generates a single file;pecmd PayrunEmployeeTestvalidates it. - Best practices are machine-readable. The codified best practices (namespace rules, naming conventions, Custom Action patterns) are accessible to the AI as context. Each new rule discovered during development is added to the corpus, improving all future regulation development.
- MCP Server provides runtime access. The AI can query the running backend to verify that imported data is correct, that lookups resolve as expected, and that payrun results match expectations — without leaving the IDE.
The composable regulation model was designed for human developers. It turns out that the same properties — structured data, clear contracts, isolated concerns — also make it ideal for AI-assisted development.
Implications for Multi-Country Expansion
If building a country regulation takes days instead of months, the economics of multi-country expansion change fundamentally.
The traditional model requires a payroll expert per country, several months of development per regulation, and ongoing maintenance as statutory parameters change annually. The cost structure scales linearly with the number of countries.
With AI-assisted development:
- The scaffold is near-instant. Repository structure, CI/CD, case definitions, empty wage types — these are generated from templates in minutes.
- The statutory research is accelerated. The AI reads tax authority publications and extracts structured data. The expert verifies rather than transcribes.
- The test suite grows with the regulation. Every Custom Action is immediately covered by integration tests. The AI generates both the implementation and its proof.
- The knowledge compounds. Every lesson learned (the
availableActionseligibility bug, thecompletedJobStatusconvention, the namespace prefix rule) is codified once and applied to every subsequent country.
This doesn’t mean every country can be built in days. Germany’s Kirchensteuer with its 16-state Hebesatz table, the Märzklausel with its multi-period social security ceiling interaction, or Spain’s 200+ convenio seniority tables — these require deep domain expertise regardless of tooling. But the mechanical work around them — the JSON scaffolding, the test generation, the report scripts — that work is where AI delivers the most leverage.
Australia is the proof point. Twelve countries, one engine, and a development velocity that makes the thirteenth country a matter of when, not if.
See AU.Payroll in the coverage matrix
Explore what the Australian regulation covers — PAYG withholding, Superannuation, Medicare, state payroll tax, and STP Phase 2 reporting — filtered in the coverage matrix.
Australia Coverage →