ADR-007: rounding_compat: pdoc computes CPP in emulated binary64
Who this is for: Engine and API contributors who touch the CPP line or the rounding_compat request field.
When you finish: You know what the pdoc arm changes, why the default keeps decimal arithmetic for the CPP line, and how floats stay out of the money path.
Status: Accepted 2026-10-22. Supersedes the fail-closed clause of ADR-003.
Context
Finding 003 inferred from PDOC's outputs (July 2026 grid, last capture 2026-09-15) that live PDOC, the CRA calculator for T4127 (Payroll Deductions Formulas), computes the period CPP contribution C in IEEE-754 binary64 and rounds half-up from the shortest round-trip decimal. PDOC's code is not public; the rule reproduces every observed CPP line. On an exact decimal half-cent such as 150.00 x 0.0595 = 8.925, binary64 holds 8.924999999999999 and PDOC shows 8.92, one cent below T4127 decimal half-up. That rule explains all 82 CPP-line disagreements in the July 2026 corpus and changes none of the 8,900 CPP lines that already agreed. ADR-003 reserved rounding_compat: pdoc for exactly this case, with the condition that the arm must not ship until the rule is named.
Decision
-
rounding_compat: pdocis implemented. It changes one line: the period CPP contribution C, and therefore whatever C feeds (F5, K2, K2P, net pay). -
The default stays
t4127: decimal arithmetic, half-up, for C. T4127 is the published formula and 8.925 is a half-cent that rounds up. The default arm is T4127 plus two PDOC-matched roundings T4127's text does not specify: the K2/K2P credits and the Ontario surtax lines are rounded separately. Flipping the default is a product decision, recorded as open in the 2026-10-22 audit. -
No float enters
takehome-core.crates/takehome-core/src/pdoc_compat.rsemulates the three binary64 operations PDOC's outputs imply (decimal to binary conversion, subtraction, multiplication, all round-to-nearest-even) on integer(mantissa, exponent)pairs, then applies the shortest-decimal half-up rule.scripts/float-ban.shstays clean. -
The emulator is judged by hardware floating point, outside the money path:
crates/takehome-core/tests/binary64_emulation.rscompares conversions, subtraction and multiplication bit for bit, and the full CPP rule on every gross cent from 0.01 to 20,000.00 at five pay-period exemptions. -
EI stays decimal in both arms: binary64
I x 0.0163breaks two EI lines that exact decimal gets right. - When the CPP annual maximum caps C, both arms use the decimal cap.
Consequences
-
Conformance publishes two rates: default
8905/9002,pdoc8987/9002. -
RequestError::RoundingCompatPdocNotImplementedis no longer returned. The variant stays in the enum so clients that match on it still compile. -
Any change to the CPP formula must keep
binary64_emulationandrounding_compattests green under both arms.
Last reviewed: 2026-10-22 Engine: 0.1.0