# Tiered Fee Calculation — frozen definition

Root freeze,25October2026. Full local package D30-F02-A04, canonical marginal tariff and separately labeled whole-amount bracket comparison. Prerequisite Idempotent Journal Posting is locally accepted; actual durable posting is outside this pure calculator. Operations will explain every fee segment; engineers will validate units, endpoints, rounding and tariff chronology. No named tariff is replicated.

All Cedar inputs/tariffs are synthetic implementation choices. Use official product/processor pricing documentation only to establish that marginal graduated and whole-amount volume methods differ; do not copy a real tariff without its full applicable terms. No tax, legal fee entitlement, overdraft authorization, currency conversion, schedule-proration or unknown-usage-completeness claim. Historical case not useful for exact synthetic tier arithmetic.

## Exact request

`schema_version`=d30-tiered-fee-v1, `calculation_id`, `ledger_id`, `entity_id`, `account_id`, `account_type`=liability, `normal_side`=credit, `currency`=USD, `period_start`, `period_end`, `knowledge_cutoff`, `mode`=marginal|whole_amount, `tariff`, `usage`. Required exact keys; Stage0 ASCII IDs and genuine Gregorian UTC milliseconds. Period is1–366 UTC dates [start,end). K>=endT00:00. Scope fields are trusted host declarations, not authenticated by strings. All outputs retain them.

Tariff exact keys: `tariff_id`, `version_id`, `currency`, `measure_unit`, `effective_from`, `effective_until`, `available_at`, `tiers`, `minimum_minor`, `cap_minor`. CurrencyUSD, unittransaction_count. Effective-from<=period_start; nullable effective-until must be>effective-from and >=period_end. Availability<=period_startT00:00 and <=K. One version must cover the whole period; an in-period change requires another split/schedule profile. An exporter must supply the actual applicable tariff; one JSON version cannot prove there was no omitted superseding version.

Usage exact keys: `quantity_units`, `measure_unit`, `period_start`, `period_end`, `available_at`, `receipt_ref`. Period/unit must match; observation>=period_endT00:00 and <=K. Quantity is a canonical nonnegative decimal string up to30digits. Host supplies a complete consistent aggregate; calculator cannot prove every transaction was counted once.

There are1–32 ordered tiers, each exactly `upper_bound_units`, `rate_microminor_per_unit`. Upper bounds are positive canonical<=30digits, strictly increasing; only the last is null for unlimited. Lower bound is previous upper, beginning0, so no gap/overlap. Per-unit fee is a canonical nonnegative<=30digit string in micro-minor units:1000000means one cent per transaction underUSD exponent2. Minimum/cap are nonnegative canonical minor strings up to30digits, cap nullable and minimum<=cap. Reject missing/unknown fields and numeric/bool/null monetary coercion. No rate is an annual interest rate.

## Arithmetic and boundaries

For quantity q, marginal allocation in tieri is max(0,min(q,upper_i)−lower_i), with null upper treated asq. Whole-amount comparison selects the first tier with q<=upper (or unlimited) and charges allq at that tier's rate; all others allocate0. Atq=100 the first100free still applies; q=101 allocates only one unit in the next marginal tier. Whole-amount discontinuities are an explicit different method.

Sum quantity_i*rate_i as exact integer micro-minor units, represent the raw fee as a reduced fraction over1000000, round-half-even once to minor units, then apply minimum and cap. No per-tier rounding. Zero usage is exempt from the minimum and produces fee0. Preserve raw exact fee, rounded-before-bounds, rounding residual, bound adjustments and ordered allocation trace. Sum of allocations=q under either mode.

Example tariff: upper100/rate0; upper1000/rate2000000; unlimited/rate1000000. Marginalq1250=>0+1800+250=2050minor; cap2000=>2000. q100=>0;q101=>2;q1000=>1800. Whole_amountq1250=>1250 before bounds. Fraction branch all-unlimited250000: q2=>1/2minor rounds0;q3=>3/4rounds1. Aggregate-rounding comparison two tiers each contributing1/2minor sums1, while per-tier half-even would incorrectlysum0. Minimum500 withpositiveusage/raw2=>500; zero usage=>0. Cap below minimum rejects.

## Complete output and accounting boundary

Always keys `status`,`code`,`fee`,`trace`,`posting_proposal`. Rejection statusrejected with typed reason, fee/proposalnull and trace[]. Success statusok/codeFEE_CALCULATED. Fee contains scope/period/K/tariff IDs/mode/unit/quantity, raw_fee_exact, rounded_before_bounds_minor, rounding_residual, minimum_applied, cap_applied, zero_usage_exemption, fee_minor. Fractions canonical reduced string numerator/denominator. Trace contains index/lower/upper/rate/allocation/exact_segment_fee; input tier order retained.

Proposal exact keys schema_version(d30-fee-proposal-v1),calculation_id,ledger_id,entity_id,account_id,currency,period_start,period_end,knowledge_cutoff,status,amount_minor,legs. Positive fee within Stage1 leg bound: statusready, Drrequested deposit liability /Crfee_income_usd. Zero: statuszero/legs[]. Above10^30−1: calculation remains inspectable, statusamount-limit/legs[], no posting-ready claim. Caller must validate chart, scope, effective/source/booking context, entitlement and stable business identity through Stage1. calculation_id is not a durable duplicate-prevention mechanism.

Required checks: exactboundaries, marginal/bracketdifference, units, zero/minimum/cap, singleaggregatehalf-even, gaps/order/nullupper, malformedquantities, wrongperspective/currency, stale/future/in-periodtariff, usageafterK/mismatchedperiod, hugeintegeramountlimit, unchangedinputs/full-outputPythonTSparity. Lab must show allocations and diagnostic sequence forcanonical1250, threshold, fraction andinvalidtariff, retaining actual reference computations rather than a decorative precomputed animation.
