What belongs here
Three kinds of boundary run through these tools, and only one of them belongs on this page.
| Kind | What happens | Where it is recorded |
|---|---|---|
| Scope | The tool never attempts it. | Each tool page, and the "what it does not do" section of each repository README. |
| Refusal | The tool stops and returns the question to a person with the reason attached. | What these tools refuse. |
| Limitation | The tool answers, and the answer rests on something the reader should be told. | This page, and LIMITATIONS.md in each package. |
Every entry below is declared at runtime by the tool that carries it, so a reader who runs the command sees the caveat whether or not they find this page. Publishing them together is for the reader deciding whether to run anything at all.
Payday Super: an exposure estimate past the rate table is withheld unless asked for
Recorded as PSC-1 against release payday-super-checker/v0.1.4. Release payday-super-checker/v0.1.6 (20 September 2026) makes the extrapolation an opt-in: a default run withholds the estimate for the row instead.
| Field | Detail |
|---|---|
| Trigger | Any day in the notional earnings period falls after the last quarter recorded in the tool’s general interest charge table, and the run was started with --allow-stale-gic. Without that flag the row keeps its verdict, its days late and its shortfall and carries no SG charge estimate at all, with a caveat naming the day, the last quarter on record and the file to update. The MCP server has no equivalent option. The published server, aus-accounting-mcp 0.3.0, pins checker 0.1.9, so a result it returns never carries an extrapolated figure. The tagged 0.1.6 Excel workbook differs: it extrapolates after 31 December 2026. The workbook version note records the 0.1.7 correction and verification scope. |
| Effect | With the flag, the last known quarterly rate is carried forward, so the notional earnings component under SGAA 1992 s 19A compounds at a rate the ATO has not published for that quarter. The administrative uplift under s 19B(1) is a percentage of shortfalls plus notional earnings, so every scenario with a non-zero uplift moves with the extrapolated figure. The percentage is not fixed: it spans 0% for the low estimate (clean 24-month history with a voluntary disclosure inside 30 days) to 60% for the high estimate (prior history, no disclosure). Both exposure totals move, including the low one: the notional earnings are added into each total before the uplift, so only the low estimate’s uplift component is unmoved, because 0% of a larger base is still nil. Do not read the low estimate as a rate-independent floor. |
| Unaffected by this rate issue | The verdict calculation does not use the GIC table. All 6 verdicts, ON_TIME, AT_RISK, LATE, UNPAID, UNKNOWN and SKIPPED, are decided by the deadline and fund receipt tests, which never read the rate table. Deadlines, business-day arithmetic, matched and remitted amounts, and the SG shortfall itself are unaffected. The exposure estimate is the only consumer of the rate. Separately, the receipt amount limitation and the matching limitations below can affect a verdict. A sound verdict does not make the row’s figures sound: a LATE or UNPAID row carries the exposure estimate this entry qualifies when the run asked for it, and shows none on a default run past the table; a SKIPPED row has no estimate to qualify. |
| Declared at runtime | Asking for the estimate is the first signal. A caveat on the result then names the table’s end date, the rate carried forward and the file to update. On a default run the caveat instead says the notional earnings and the SG charge estimate were not assessed for that row, and the five charge columns of report.csv are empty rather than nil. |
| Human step | Update the rate table from the ATO general interest charge rates page rather than passing --allow-stale-gic. Rerun and confirm the caveat is gone before relying on an exposure figure. |
| Status | Narrowed in v0.1.6. The extrapolation used to run behind a caveat the reader had to notice, which put an unpublished rate into both exposure totals by default. It is now an opt-in, so a default run either has a published rate for every day of the period or withholds the estimate for that row. The shortfall figure is reported either way; its reliability still depends on the supplied amounts and matching evidence. |
Payday Super: the payroll-to-super join degrades in four declared ways
Recorded as PSC-2 against release payday-super-checker/v0.1.4. Each condition weakens the join that every verdict rests on, so a verdict can be wrong without any arithmetic being wrong. Release payday-super-checker/v0.1.5 (20 September 2026) carries each warning into the report’s caveats column and the evidence pack; the four conditions are unchanged.
| Condition in the supplied exports | Effect on matching |
|---|---|
| Either file has a blank employee id on any row | Matching falls back to employee name. Two employees sharing a name are merged. |
| The payroll file has no pay-period-end column | Matching falls back to the payday. A super payment recorded against the pay period rather than the payday can be missed. |
| The super file has only one of pay period start or end | A payment’s coverage collapses to a single day and can miss the payday it actually settled. |
| The super file has no pay period columns at all | A payment is treated as covering every payday for that employee. Where it cannot cover every competing balance, the tool refuses only if two or more of the still-competing payroll rows are identical in payday, effective period end and amount. Rows differing in any of those three are sorted and apportioned, not refused. |
Unaffected by the join itself. Matching selects the rows and amounts sent to assessment; it does not change the downstream deadline, receipt or exposure rules. Their results still depend on receipt amount evidence, calendar and GIC coverage, and the other documented limits. Correct arithmetic cannot establish that a payment was matched to the right payday or that the fund received it.
Declared at runtime, on the console only in 0.1.4. One structural warning per condition, printed ahead of every row-level warning and never truncated, because these govern whether the whole join can be trusted. The report header also states the key in use as employee matching: by id or by name. The CSV carries each row’s caveats and notes and a trailing provenance note, not these warnings, so anything downstream of the file, including a spreadsheet built from it, can present an affected verdict without them. Keep the console output with the pack, or rerun and read it, before relying on a verdict from a file whose join conditions you have not checked.
Human step. Re-export with an employee id column on both files, a pay-period-end column on the payroll file, and pay period start and end columns on the super file. All three are needed: fixing only the ids still leaves the payday fallback and the coverage collapse in place. Where a re-export is not available, reconcile the affected employees by hand before relying on their verdicts.
ATO benchmarks: an unmapped bucket reads as a nil in one output and as withheld in the other
Recorded as ABC-1 against release ato-benchmark-compare/v0.1.7. Release ato-benchmark-compare/v0.1.8 (20 September 2026) gates the command line text, JSON and exit code on the buckets the mapping supplied. A bucket no account was mapped to reads not_supplied on both paths, and the key ratio stays the ATO’s published one where cost of sales was not supplied. The entry below describes 0.1.7.
A bucket a ratio needs is absent from the supplied totals, and reaches the comparison as exactly the nil that a genuine zero produces. Where that bucket is cost of sales and the business type’s key ratio is cost of sales to turnover, the ATO’s own fallback to total expenses triggers on that nil, so the effect also reaches which ratio is marked key. The two output paths resolve this differently, on purpose, for the same comparison.
This is not the same as a profit and loss account with no mapping entry. The tool raises a mapping error listing the first 20 unmapped rows and a count of any beyond that, and the command line exits before any comparison happens, so that input reaches neither output path. The trigger here is a bucket that no account was mapped to: the mapping is complete, the bucket simply has nothing in it.
| Behaviour | Command line text and JSON | Python library payload |
|---|---|---|
| A ratio whose buckets were not supplied | Emitted as a computed figure, typically 0.0000, with no marker separating it from an established nil. | Value withheld as null, status not_supplied. |
| The key ratio when cost of sales is unmapped | Carries the ATO fallback to total expenses to turnover, with the fallback note present. | Reverts to the business type’s published key ratio, with the per-row key flag reverting alongside it. |
The command line receives no record of which buckets were supplied, so it cannot tell an unmapped bucket from a nil one. The library payload is told, and can.
What stays correct. The comparison behind both. Each path renders one comparison built from one mapping, so turnover, the turnover basis and every computed figure are the same on both sides.
Parity at the row level is narrower, and needs two conditions together. First, the ratio’s own buckets are supplied: total expenses to turnover needs every expense bucket, labour to turnover needs the labour set plus payments to associated persons once w1 is supplied, and the rest need their own field. Second, both income fields are supplied, turnover and other income together. Without both, even a ratio holding all of its own buckets is emitted by the command line and withheld by the library. Where both conditions hold, the row carries the same value in both against the same published range.
Three things diverge independently, and running them together overstates the effect.
| What | When it diverges |
|---|---|
| A ratio’s value | Its own buckets are absent, or an income field is. The library withholds it as not_supplied; the command line emits a figure. |
| A ratio’s benchmark range | Only when an income field is absent. With both income fields supplied the range is retained, even on a row whose value is withheld. |
| The key ratio and its flag | Only in the cost of sales fallback above. A missing non-key bucket leaves the key ratio and every key flag alone. |
Do not read the two payloads as interchangeable.
Human step. Map an account to every bucket the ratios you intend to read require, including a deliberate nil where the business genuinely has none. Where a figure must not be shown unless it was established, read the library payload: a not_supplied status is the honest answer that a command line 0.0000 cannot give. Where a business genuinely has no cost of sales, the fallback is the ATO’s own behaviour and the result stands.
Telling me a number is wrong
The most useful report carries the command you ran, the output it produced, the figure you expected and where that expectation comes from. A primary source, a worked example from the regulator or a second implementation all work. Open an issue on the repository that carries the tool, or use the contact page.
Two implementations disagreeing is the cheapest way to find a defect, and the disagreement is worth reporting even when you are not certain which side is right.
What this page is not
This is a register of limitations found and confirmed, not a proof that none remain. An absent entry means nothing has been established and recorded, not that a tool is correct everywhere else. Each entry is bound to the behaviour it describes by a test in its package, so a fix fails the test and forces the entry to be updated, but the register cannot report what has not been found. The evaluations reproduce the passing cases against fixed releases, and Evidence and Assurance records the review boundaries and the absence of third-party review.