Schedule icon
OutputValues icon
If icon
Fail icon
Queries icon
Log icon
Write icon
UploadFiles icon
Switch icon
Set icon

Test debt covenants every quarter and draft the compliance certificate

Quarterly debt covenant test in Kestra and DuckDB. Frozen GAAP EBITDA, capped add-backs, step-downs, headroom, forecast, equity cure, certificate.

Categories
BusinessData

A company with a bank facility sends a compliance certificate every quarter: leverage, interest cover and liquidity, computed exactly as the agreement defines them, signed by a director. A breach is an event of default. A breach found late leaves no time to cure it. The definitions rarely match the published accounts:

  • EBITDA is often pre-IFRS 16 ("frozen GAAP"),
  • add-backs for one-off costs are capped,
  • levels step down over the life of the loan.

This flow runs the test from the trial balance, explains every figure, warns two quarters ahead, and drafts the certificate.

It runs with no setup and no network. DuckDB generates a monthly year-to-date trial balance from October 2024, with a term loan amortizing 1,000,000 a quarter, a 15,000,000 revolver, IFRS 16 lease accounts and restructuring costs in three months. The demo has three scenarios:

  • CLEAN: the business performs to plan;
  • STRESS: revenue falls 32% from September 2026 while costs do not flex;
  • ISSUES: a month is missing from the trial balance and another does not balance.

This blueprint was created by zkasuran.

Definitions, as in a typical agreement

Figure Definition
EBITDA Revenue - cost of sales - operating expenses - non-recurring items, last 12 months, from year-to-date balances
Add-backs Non-recurring items added back, capped at addback_cap_pct of EBITDA before add-backs. The disallowed part is shown
Frozen GAAP Lease payments deducted from EBITDA, lease liabilities and lease interest excluded. Set frozen_gaap: false to test on IFRS 16 figures
Net debt Term loan + revolver drawn - cash (+ leases under IFRS 16)
Net finance charges Interest on borrowings - interest income (+ lease interest under IFRS 16)
Liquidity Cash + undrawn revolver
Capex Year to date, annualized

The covenants and their step-downs live in one table (covenant_levels): net leverage at most 3.50x, then 3.25x from June 2026 and 3.00x from December 2026; interest cover at least 4.00x; liquidity at least 10,000,000; capex at most 8,500,000.

What each test produces

  • Pass or fail, against the level in force on the test date.
  • Headroom: for ratios, how far EBITDA can fall before the covenant breaks. For amounts, the margin over the limit.
  • Forecast: the same tests at the next two quarter ends, with the months after the test date taken from the forecast. A breach or a headroom under 10% is reported, so a breach at a step-down is seen a quarter ahead.
  • Equity cure: on a breach, the cash injection that would cure it, applied to net debt. A debt cure can fix leverage and liquidity, but not interest cover. At most 2 cures over the life of the facility, never in consecutive quarters, tracked in KV.
  • Compliance certificate: a Markdown draft with each clause, the figure, the limit, the EBITDA bridge and the cure if one was applied, signed by approved_by.

How it works

  1. state reads the certified tests and the cures used. order_gate refuses a quarter already certified, or one whose previous quarter was not.
  2. test (io.kestra.plugin.jdbc.duckdb.Queries) builds the trial balance and checks that no month is missing and every month balances. It then computes the figures at the test date and the next two quarter ends, and runs the tests, headroom, cure sizing and the certificate.
  3. log_test prints the test. write_certificate (io.kestra.plugin.core.storage.Write) and evidence store definitions.csv, tests.csv, forecast.csv, blockers.csv and compliance-certificate.md.
  4. decide (io.kestra.plugin.core.flow.Switch):
    • CERTIFY: records the test, and the cure if one was applied.
    • Otherwise it fails with what to do: DATA_ERROR, CURE_NOT_AVAILABLE, BREACH (with the cure needed, or the advice to seek a waiver) or NEEDS_SIGNATURE.

Tested end to end

On Kestra 2.0.3 OSS, in this order.

Run Inputs Result
1 2026-06-30 EBITDA 18,388,082 after capping the 900,000 add-back (570,174 disallowed). Net leverage 2.17x against 3.25x (headroom 33.1%), interest cover 6.13x. All pass. Stops for a signature
2 same, signed Certified
3 2026-09-30 STRESS, signed Compliant (leverage 2.32x), certified, with a warning: December leverage projected at 3.05x against the new 3.00x level
4 2026-09-30 again / 2027-03-31 Refused: already certified / December not yet certified
5 2026-12-31 STRESS Breach: leverage 3.05x against 3.00x. Cure needed 752,670
6 same, equity_cure_amount: 752670 Leverage 3.00x, certified. The certificate shows the cure under clause 22.4
7 2027-03-31 STRESS with a cure Refused: the previous quarter was cured
8 2027-03-31 STRESS Breach on leverage, interest cover and liquidity. Interest cover cannot be cured with equity: the flow advises a waiver
9 2027-03-31 ISSUES Stopped: November 2026 missing, February 2027 out of balance by 125,000.00
10 2026-06-30, frozen_gaap: false EBITDA 23,428,082 and net debt 52,178,349 with leases. Leverage 2.23x

Problems found while testing

  • The trial balance did not look like a trial balance. The first version stored P&L movements per month and balanced equity against the cumulative result since the start. Real trial balances carry year-to-date P&L. It now does too, and the last twelve months come from YTD now + last December - YTD a year ago. The LTM EBITDA at three test dates matched the earlier movement-based figures to the euro.
  • The cure advice was wrong for interest cover. It proposed a cash amount for a breach that cash cannot cure. Breaches are now split into curable and not curable.
  • The stress broke the wrong covenant. The first stress drained cash and broke liquidity before leverage. It was recalibrated so the step-down breaks first, which is the case the forecast warning is for.

Inputs

Input Default Purpose
test_date 2026-06-30 A quarter end, validated
scenario CLEAN Demo only
frozen_gaap true Pre-IFRS 16 definitions
addback_cap_pct 10.0 Cap on non-recurring add-backs
equity_cure_amount 0.0 A cure to apply
approved_by empty The director who signs

Use it with your data

  • Replace tb with your monthly consolidated trial balance, with P&L year to date and balance sheet at month end, mapped to the accounts used here.
  • Lease payments and capex come from memo accounts. Take them from the cash flow or the lease system.
  • Put forecast months into the same table with the forecast figures.
  • Edit covenant_levels and the clause references to match your agreement, and rcf_commitment to your revolver.

Things to know

  • This is a calculation aid. The agreement's definitions decide, and a borderline result should be reviewed with the lenders' counsel.
  • Pro forma adjustments for acquisitions and disposals, and EBITDA cures (as opposed to debt cures), are not modelled.
  • Reset the history by deleting the KV key covenant_tests.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.