An invitation and a standard for anyone building bounded, deterministic
tax and accounting tools.
LodgeiT Labs · September 2026 · draft v2
We run a small fleet of deterministic Australian tax and accounting calculators behind one public front door — no key, no signup, built so an agent can call them without a human in the loop (see lodgeit.org/calculators.html and lodgeit.org/llms.txt). Depreciation, Division 7A and nineteen FBT benefit categories are live, and a trial-balance classifier (Fano) joined them this week.
We are not going to build the rest of the world's tax and accounting algorithms ourselves. There are a million of them across jurisdictions and we'd like to point at other people's — provided they meet a standard an agent can rely on. If you already show the branch, the formula, the evidence state and the rounding — and refuse when the supplied facts do not settle the test — you are most of the way there.
This document sets out what "meeting the standard" means today, what we'd do with a calculator that meets it, and how we intend to help you earn from it as the platform matures. We are candid throughout about what exists now and what is still planned.
A constellation calculator is a deterministic engine — no model in the path — behind an HTTP surface that describes itself, validates the request and refuses what it cannot answer, names every statutory input it consumed, and returns money as exact decimals. Everything below is an elaboration of those four properties.
An agent should be able to go from your base URL to a correct first call without reading prose.
Naming conventions we use, and would ask you to follow so the registry can index by them:
| Thing | Pattern | Example |
|---|---|---|
| Calculator | urn:sbrm:calculator:{module}:{name} | urn:sbrm:calculator:fbt:car-operating-cost |
| Period | urn:sbrm:period:{module}:{scope} | urn:sbrm:period:fbt:fy2026 |
| Rate table | urn:sbrm:rate:{module}:{period}:{rate-type} | urn:sbrm:rate:div7a:fy2026:benchmark-interest |
If a calculator has no period dependence, use the scope unscoped.
Every calculator declares a module (the URN’s second-last segment, e.g. urn:sbrm:module:fbt) and a short description of when to use it and when not to. Where a benefit type is served by more than one valuation method, each calculator also declares a selection.kind — fact, election or statutory_default — so an agent computes every method the records support and lets the client elect, rather than choosing one. GET /v1/modules lists the modules and their calculators; GET /v1/calculators?module= filters to one.
Refusals are a feature. The status code is a contractual signal, not an error to hide:
| Code | Meaning | Body must include |
|---|---|---|
200 | Computed | results + manifest + advisory |
422 | Malformed or incomplete request | the field that failed |
400 | Well-formed but outside what the calculator can answer | refusal_class and a one-line reason |
404 | Unknown calculator URN or unsupported period URN | which one |
5xx | Service fault; the caller may retry | nothing sensitive |
A 400 is exactly your "supplied facts do not settle the test" case. Give it a stable
refusal_class string an agent can branch on (out_of_scope_period,
insufficient_facts, unsupported_entity, and so on — publish your own list
in the OpenAPI document).
Every 200 carries a manifest: the rate tables and statutory
parameters the calculation actually used, each with a SHA-256 of the table's content as served by
/v1/rates/{period_uri}. This is what lets a caller detect that a rate changed between
two calls months apart, and it is what our bounty reviewers check against the legislation.
"manifest": {
"calculator": "urn:sbrm:calculator:payroll-levy:levy",
"period": "urn:sbrm:period:payroll-levy:fy2026",
"rate_table_uris": [
{ "uri": "urn:sbrm:rate:payroll-levy:fy2026:levy-rate", "sha256": "…" }
],
"engine": "payroll-levy/1.2.0",
"citation": " , s "
}
Alongside it, an advisory block: what kind of figure this is and what it is not — your "review aid, not a compliance determination" language belongs here, as structured text the agent will pass to the human.
"advisory": {
"figure_type": "payroll_levy_estimate",
"notes": [
"Review aid for a qualified professional; not a lodgement figure.",
"Assumes eligible wages as supplied; eligibility under s 3B is not tested here."
]
}
Money and rates are returned as decimal strings, never JSON floats:
"9830.60", not 9830.6. Beyond representation, the constellation has one
rounding standard:
ROUND_HALF_UP, MidpointRounding.AwayFromZero, Excel ROUND).
Rates and factors emit at 4 dp on the same rule; the emitted scale is stated in the schema.422 naming the field — never silently rounded.A conformant calculator states in its advisory which of rules 3, 5, 6 and 7 apply to it, and names the rounding policy in force in its manifest beside the rate-table hashes. This is the single most common way an otherwise-correct calculator fails a review.
Same request, same period, same rate-table hashes → byte-identical result. No model, no external lookup at call time other than your own rate tables, no clock dependence except through the period URN. Publish a small fixture — a handful of requests with expected responses — in your repository; we will run it against your live endpoint as part of listing, and again whenever you tell us you've changed something.
The constellation model is open access: no key, no signup. Bound your own cost the way we do — a
small instance cap on whatever you host on, and request guards (body size, a per-IP rate limit
returning 429 with Retry-After). Tell callers the limits in your discovery
response. You host it; we point at it. Cloud Run, a VPS, or a browser-side calculator with a thin
HTTP wrapper are all fine, so long as the URL is stable and the surface above is present.
Today (manual, but real):
llms.txt as an external entry with your name on it, status available, linking to your repository and base URL. Agents that already read our llms.txt will find it the same day.Planned (the parts that make this scale, in the order we'll build them):
llms.txt grown up: one index entry per calculator carrying base URL, manifest schema, jurisdiction, conformance result and attestation tier. Tiers are how a million entries stay usable: unattested → conformance-passed → practitioner-attested → jurisdiction-owned. An agent reads the tier before it calls.ACCEPT / REJECT / FIX verdicts become public, hash-receipted records. Your calculator would be eligible for the same review, and a practitioner-attested tier is what a conservative accountant will trust: not because a model said so, but because a named peer tried to break the deterministic engine and couldn't.None of this is live yet, and we'd rather say so than imply otherwise. The design is:
L402 at your endpoint. L402 is the Lightning-native HTTP payment flow: a call
without payment returns 402 with an invoice; the caller (typically an agent) pays a few
satoshis and retries with the proof. It is machine-native and needs no signup, which is the same "no
key" philosophy applied to money. Because it lives at your endpoint, payment goes to
you directly; there is no intermediary holding your revenue.
What LodgeiT earns, and from what. We charge for what we actually provide — discovery and attestation — as a routing fee on calls that come through our gateway or MCP surface, and nothing on calls that reach you directly. A listing in the registry is free; a practitioner attestation, once you've earned it, is what drives traffic to you, and that traffic is what you're paid on.
Order of operations. Contract and conformance first (nothing to pay for until a
caller can trust the thing it's paying for), registry and tiers second, L402 third. We expect the
first two within the next quarter; the third depends on them. If you'd rather not touch Lightning,
an unpaid listing is still worth having — the agents are already reading llms.txt.
Take one deterministic calculator you already have and put it behind the surface in §1–§4:
discovery, 422/400/404 refusals with a refusal_class, a manifest naming the
rate table with its hash and the statutory citation, decimal-string money, and a five-case fixture in
the repo. Send us the base URL. We'll run the fixture and the conformance pass, and if it clears, it
is on the page and in llms.txt the same week — the first calculator in the constellation
that we didn't write.
If something in the standard doesn't fit your tool, say so; the spec is young and you are the kind of author it's meant to serve.
— Andrew Noble, LodgeiT Labs
andrew@lodgeit.net.au