Privacy budgets
The platform represents each privacy allowance as one frozen value object:
PureDPBudget(eps)ApproxDPBudget(eps, delta)ZCDPBudget(rho)
Algorithms receive the allowance through one interface:
Budget objects have no arithmetic or conversion methods. They remain typed through delegation and composition; a mechanism extracts a bare epsilon or rho only where it performs the corresponding privacy arithmetic.
Spending across privacy families
dp_testing_platform.core.accounting is the single conversion boundary. A mechanism
may spend an offered allowance only by realizing a guarantee that implies the offered
family.
| Offered allowance | Pure-DP mechanism | zCDP mechanism | Gaussian mechanism |
|---|---|---|---|
PureDPBudget(eps) |
spend eps |
refused | refused |
ApproxDPBudget(eps, delta) |
spend eps; delta remains unused |
spend the largest rho admitted by the implemented sound conversion | analytic-Gaussian calibration |
ZCDPBudget(rho) |
spend sqrt(2*rho) |
spend rho |
sigma = sensitivity / sqrt(2*rho) |
The helpers are accounting.spend_as_pure, accounting.spend_as_zcdp, and
accounting.calibrate_gaussian_sigma. Unsupported directions raise instead of
silently weakening the guarantee. Native approximate-DP mechanisms whose theorem
does not pass through one of these conversions require ApproxDPBudget directly.
The pure-DP-to-zCDP and Gaussian-to-zCDP rows follow Bun and Steinke, “Concentrated Differential Privacy”, Propositions 1.4 and 1.6. Approximate-DP Gaussian calibration follows Balle and Wang, “Improving the Gaussian Mechanism for Differential Privacy”.
Constructing evaluation grids
Concrete budgets are the primary engine axis:
from dp_testing_platform import (
ApproxDPBudget,
PureDPBudget,
ZCDPBudget,
run_experiment,
)
budgets = [
PureDPBudget(1.0),
ApproxDPBudget(1.0, 1e-5),
ZCDPBudget(0.5),
]
results = run_experiment(
task,
algorithms,
instance_generators,
budgets=budgets,
)
The CLI flags --epsilons and --deltas are convenience syntax. An omitted delta,
or a delta of zero, constructs a pure-DP budget; a positive delta constructs an
approximate-DP budget. Identical realized budgets are deduplicated while preserving
their first occurrence.
Budgets may depend on public instance metadata. For example, a caller can construct
ApproxDPBudget(eps, 1 / metadata.n_samples**2). The engine stores the concrete
allowance that each cell actually received; it does not persist or infer a budget rule.
Result identity
Each result records the canonical dataclass representation in budget, for example
PureDPBudget(eps=1.0) or ZCDPBudget(rho=0.5). That string is the privacy-budget
part of row identity and of the output-sidecar key. The non-identity convenience
columns budget_family, eps, delta, and rho make filtering and plotting easy;
parameters that do not apply to a family are blank. Never reconstruct identity from
those convenience columns. Budget class and field names are therefore storage-schema
elements; renaming one requires an explicit migration of persisted records.
Our class-based budget setup is similar to that employed by Tumult Analytics.