Specification · salestax @ 0.1

salestax — Sales Tax · Area Specification

last conformance run: 4/4 scenarios pass · 5 acts mapped 2026-10-24 20:36 UTC

Spec

Status: 0.1. The sales tax return for a period, from what was invoiced and credited: taxable and non-taxable sales, the tax charged at each rate, the tax given back on credits, and what is due. Then the filing a person records, the payment that follows, and the liability in the books beside it. Invoices already carry their tax; this closes the loop.

1. Calibration: who this is for

A small business that charges sales tax and files monthly or quarterly with one agency. The owner wants the return's numbers without building a spreadsheet: what was sold, what was taxed, what came back, what is due. The accountant wants a filed period to stay what was filed, and anything that changed it afterwards to be named.

2. Scope

In: the return for a month, a quarter or a year; credit notes giving back the tax inside them; recording a filing (a person's act) and its payment; the liability against Sales Tax Payable in the books; changes to filed periods carried to the next return.

Out (§9): several agencies or jurisdictions per space, determining rates (the rate on each line is the one the invoice charged), exemption certificates, bad-debt relief, use tax on purchases, and filing with an agency.

3. Entities and lifecycles

4. The acts

Writes: record_filing (a person's act), record_payment.

Reads: return (a period's figures and changes to filed periods), liability (owed as of a day, beside the books, and each month's standing), filings.

5. Invariants

6. Required read models

return (gross, non-taxable, taxable, by rate, credits, due, changes to filed periods, whether filed), liability (owed, the books, ties, months with their state), filings (filed, paid, balance, changed since).

7. Contract vs freedom

Contract: tax as charged, credits giving tax back, the person's filing kept as it stood, payments recorded not made, a liability that ties. Freedom: how often to file, the agency's name.

8. Conformance (scenarios)

01 a month's return: taxable and non-taxable sales and the tax due · 02 the agent cannot record a filing · 03 the liability ties to the books · 04 a payment needs a filing. The person's filing, the payment, the credit giving tax back and the changed-since check are contract gate 21, because scenarios run as an agent.

9. Out of scope, on purpose

Several jurisdictions in one space, rate lookup by address, exemption certificates, bad-debt relief, use tax on purchases, and filing itself: these books record what the person filed and paid, and never contact an agency.

Acts

ActKindRequired
returnreadnone
liabilityreadnone
filingsreadnone
record_filingwriteperiod filed_amount filed_on reason
record_paymentwritefiling amount paid_on

Invariants

IdInvariant
TAX-1Money is integer cents; each line's tax is what the invoice charged, never recomputed.
TAX-2Tax due is tax charged on invoices in the period less the tax inside credits raised in it; a write-off gives none back.
TAX-3Recording a filing is a person's act, with a reason, refused to an agent whatever its role.
TAX-4A filing keeps the return as it stood; a later change shows as changed since and is named on the next return.
TAX-5A filed amount that differs needs a reason; an unfinished period cannot be filed; filed periods never overlap.
TAX-6Payments are recorded, never made, never exceed what is owed, and wait in the bank reconciliation.
TAX-7Sales Tax Payable equals tax charged less tax given back less payments; a difference is named.
TAX-8Every write is a logged command with an actor; refusals are logged too.

Scenarios

Each scenario is a file of acts with expected outcomes. ok means the act must succeed with the listed fields; refused means the act must be refused with a sentence containing the listed text. Refusals are contract.

a month's return: taxable and non-taxable sales and the tax due pass

TAX-1, TAX-2: the tax on each line as charged; installation is not taxed.
Environment: set_company_profile, create_customer, draft_invoice, issue_invoice
#ActExpectWhy
1returnok gross=150000 taxable=100000 nontaxable=50000 tax_collected=8750 due=8750TAX-2

the agent cannot record a filing pass

TAX-3: recording a filing is the person's act, whatever the agent's role; the refusal is logged.
Environment: set_company_profile, create_customer, draft_invoice, issue_invoice
#ActExpectWhy
1record_filingrefused person's actTAX-3
2filingsok count=0

the liability ties to the books pass

TAX-7: Sales Tax Payable in the books equals the tax charged, nothing paid yet.
Environment: set_company_profile, create_customer, draft_invoice, issue_invoice
#ActExpectWhy
1liabilityok owed=8750 books=8750 ties=trueTAX-7

a payment needs a filing pass

TAX-6: a payment is recorded against a filed return; with none filed it is refused.
Environment: set_company_profile, create_customer, draft_invoice, issue_invoice
#ActExpectWhy
1record_paymentrefused does not existTAX-6

These pages are generated from the files in specs/ in the repository; scenarios are executed by src/conformance.js on every build. Written and maintained by Peter Varga, who also runs Portland AI Works. github.com/alviso/saybooks, AGPL-3.0.