money-handling
Skill1 starsChanged 43 days agoMITView on GitHub
Use when code stores, computes, converts, compares, or displays monetary amounts or currencies
In this repository5 other files it gives its agents.
- snippets/CLAUDE.mdCLAUDE.md
- idempotencySkill
- safe-migrationsSkill
- timeouts-and-retriesSkill
- transaction-boundariesSkill
The file
We split this skill into the rules it gives an agent
4 rules. About 0 are common, 2 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 17
Never float or double. Use integer minor units (long cents) or BigDecimal with an explicit scale.
- Very specific: line 20
Every division or scale change names its RoundingMode.
- Distinctive: line 22
When splitting an amount (shares, installments), the parts must sum to the total.
- Distinctive: line 43
No currency anywhere, so nothing stops a USD amount being compared with an EUR one.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Money handling
Money bugs are quiet. They show up as a cent off here and there, found months later by reconciliation.
When to use
- Any field, column, or calculation that represents an amount.
- Fees, taxes, discounts, splits, currency conversion, or comparing amounts.
Checklist
- Never
floatordouble. Use integer minor units (longcents) orBigDecimalwith an explicit scale. - An amount always travels with its currency. Never add or compare across currencies.
- The number of decimal places depends on the currency (JPY has 0, KWD has 3). Take it from ISO 4217 data, for example
Currency.getDefaultFractionDigits(), never from a hardcoded 2. It returns -1 for pseudo-currencies such as XXX, so reject those. - Every division or scale change names its
RoundingMode.BigDecimal.dividewithout one throws on non-terminating results. Document the business rule you chose. BigDecimal.equalscompares scale, so2.0does not equal2.00. Compare withcompareTo.- When splitting an amount (shares, installments), the parts must sum to the total. Distribute the remainder explicitly instead of rounding each part.
- In JSON, send amounts as strings or as integer minor units, not as floating-point numbers. In the database use
numeric(p, s)orbigint, neverfloatordouble precision. - For conversion, record the rate, its timestamp, and its source, and convert once at a defined point.
Bad example
double total = 0;
for (Line l : lines) {
total += l.getPrice() * l.getQty() * 1.17; // price + VAT
}
if (total == invoice.getAmount()) {
markPaid();
}
return total; // serialized as a JSON numberWhat to flag
doublefor money:0.1 + 0.2is not0.3, and errors accumulate across lines.==on floating-point amounts will miss equal values and may match different ones.- No currency anywhere, so nothing stops a USD amount being compared with an EUR one.
- VAT applied per line with no rounding rule: the total can differ from the invoice by a cent.
- The result is serialized as a JSON number, which clients may parse as a float.
Good example
Currency currency = invoice.currency();
BigDecimal vatFactor = new BigDecimal("1.17"); // 17% VAT as a multiplier
BigDecimal net = lines.stream()
.map(l -> l.unitPrice().multiply(BigDecimal.valueOf(l.qty())))
.reduce(BigDecimal.ZERO, BigDecimal::add);
// Rounding rule: HALF_EVEN here. Use whatever your jurisdiction or contract requires.
int scale = currency.getDefaultFractionDigits();
if (scale < 0) throw new IllegalArgumentException("no minor unit: " + currency);
BigDecimal gross = net.multiply(vatFactor).setScale(scale, RoundingMode.HALF_EVEN);
if (gross.compareTo(invoice.amount()) == 0) {
markPaid();
}
return gross.toPlainString(); // string, not a floatRounding once, at the end, with a named mode, keeps the total predictable. If the business rule is to round per line, say so in the code and round each line with the same mode.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

