← Back

2026-09-06

The Suspended Account Problem: Why BES Participants Under Legal Injunction Create a Reporting State Your Pipeline Was Never Designed to Hold

Every pension operations team in Turkey has met this ticket at least once: a court orders a freeze on a participant's BES account, someone in legal forwards the tebligat to operations, and a flag gets set in the participant master. Two weeks later HAYMER validation fails, the state contribution file is rejected by EGM, or worse — the participant's NAV is silently wrong for a month and nobody notices until a reconciliation officer runs a spot check.

The reason is almost always the same. The injunction was modeled as a boolean on the account, not as a temporally scoped constraint that has to travel through every downstream process the account participates in.

The legal state and the operational state diverge on day one

A haciz or ihtiyati tedbir on a BES account does not stop the pension machinery. Payroll systems keep sending contributions. The fund keeps valuing daily. The state contribution accrual keeps calculating based on eligible contribution amounts. EGM still expects the daily participant snapshot and the monthly HAYMER submission to reconcile.

What the injunction actually does is narrow: it prevents the participant from exercising certain rights — typically exit, transfer, partial withdrawal, and sometimes fund allocation changes. It does not prevent contribution inflow. It does not pause NAV allocation. It does not remove the account from the pension universe.

So from day one you have two states running in parallel:

Most pipelines conflate these. A single is_suspended flag on the participant record ends up being read by six different jobs, each interpreting it slightly differently.

Where the flag-based model breaks

Consider a concrete case. Participant X has an active injunction filed on the 12th of the month. Contributions for the month arrive on the 15th (payroll cycle). State contribution eligibility is calculated on month-end. HAYMER file goes out on the 5th of the following month.

If your NAV allocation job reads is_suspended = true and skips the participant, you have just failed to allocate units for a contribution that legally must be allocated. The money sits in a suspense account with no unit backing. Next day's NAV total does not tie.

If your state contribution job reads the same flag and excludes the participant, you have withheld a state contribution the participant is entitled to — the injunction restricts withdrawal, not accrual.

If your HAYMER extract reads the flag and marks the account as passive or excluded, EGM will reject the file because yesterday it was active with a balance and today it disappeared without a valid status transition code.

Each job is behaving reasonably in isolation. Together they produce an incoherent participant record.

Temporal scoping is the missing primitive

The injunction is not a property of the account. It is an event with:

Modeling this as an event table — one row per injunction with start, end, scope — and joining it into each pipeline stage with the correct temporal filter is not exotic. It is the same pattern you already use for fund allocation history or contribution rate changes. The problem is that legal restrictions almost always enter the system through a manual operational channel, get flattened into a flag by the first person who touches them, and lose the temporal and scope dimensions before any code sees them.

What the pipeline should actually do

For each pipeline stage, the question is not "is this account suspended?" It is "on the effective date of this operation, does the active injunction scope prohibit this specific action?"

Concretely:

The reconciliation trap

The worst version of this problem shows up months later during reconciliation. An account under injunction accumulates contributions and units correctly, but a downstream report — usually one built by a business user in an ad hoc tool — filters out "suspended" accounts. The management dashboard undercounts AUM. The actuarial extract misses liabilities. Nobody notices until year-end.

The fix is not to hunt down every filter. The fix is to stop exposing a single suspended boolean at all. Expose the injunction event table with its scope, and force every consumer to ask the specific question they actually care about. If a report author has to write where not exists (select 1 from account_restriction where scope includes 'reporting_exclusion'), they will think twice before excluding accounts they should not exclude.

Where to put the boundary

In practice the cleanest place to enforce this is at the operation authorization layer, not in the individual jobs. Every participant-initiated operation goes through a single check that consults the active injunctions with the correct scope filter. NAV, contribution, and reporting jobs never look at injunction data at all — they operate on the full active participant set, and the injunction only ever surfaces when someone tries to do something the court has forbidden.

This inverts the common design. Instead of every job asking "should I skip this account?", only the operations that can actually be blocked ask "am I allowed to proceed?". Everything else runs as if the injunction does not exist — because operationally, for those processes, it does not.

The suspended account is not a special case that needs to be filtered out. It is a normal account with a narrow set of prohibited actions. Build the pipeline that way and the HAYMER rejections stop, the NAV ties, and the reconciliation officer stops finding surprises in March.