· 2 min read
A finalized payroll run must recompute to the same centavo forever
Statutory tables change. Contribution schedules get revised. If a payroll run from March recomputes differently in November, the payslip you handed someone was a guess. Here is how Cayamanan makes that impossible.
iBAS Software FR

Ask most payroll systems to reopen a run from two years ago and they will happily recompute it. That sounds like a feature. It is the single most dangerous thing a payroll system can do.
Why recomputation drifts
Philippine statutory schedules are not constants. The SSS contribution table has been revised repeatedly, each revision with its own effective date. PhilHealth premium rates step up on a published schedule. The BIR withholding tables changed with the TRAIN law and will change again. Pag-IBIG has its own thresholds.
A payroll engine that reads "the SSS table" reads whatever is in the table today. Recompute a March 2024 run in November 2026 and you get November 2026 rates applied to March 2024 earnings. The number that comes out is not wrong arithmetic. It is arithmetic against the wrong law.
The failure is quiet. Nobody sees it until an audit, a dispute, or a separation pay computation that has to reach back years.
Effective dating is not a nice-to-have
Every statutory table in Cayamanan is versioned with an effective range, and every run records which version it used. The run does not ask "what is the SSS bracket for this salary". It asks "what was the SSS bracket for this salary, under the schedule in force on this cutoff date".
The same rule applies to the employee's own record. A salary change does not overwrite the old salary. It closes one row and opens another. When payroll asks what someone earned in the second cutoff of March, the answer is a historical fact, not the current value of a field.
Nothing is ever overwritten. A salary change closes one row and opens another.
This is why employment and compensation is milestone three and payroll is milestone four. You cannot build a correct payroll engine on top of records that lose their own history. The prerequisite is not optional.
Finalized means finalized
Once a run is finalized it stops being a calculation and becomes a record. Configuration changes after that point do not touch it. If a rate was wrong, the correction is an explicit adjustment with its own audit trail, visible as a correction, not a silent rewrite of what somebody was told they earned.
That is a deliberate constraint on the software. It means more tables, more effective-dated joins, and more work in every query. It also means the payslip you handed someone in March is still exactly reproducible in November, which is the only property that makes a payroll system trustworthy.
What this costs
Exact decimal arithmetic throughout, with rounding always explicit and named. No floating point anywhere near money, because binary floats cannot represent a centavo exactly and the error compounds across a thousand employees.
None of this is clever. It is just the unglamorous version of the work, done in the order that makes the last step possible.

