# Audit Specs `AuditSpec` is a serializable configuration object for standard `updatesupport` audits. Use it when an audit should be reproducible, checked into a model-review folder, generated by another system, or rerun in CI. ```python import updatesupport as us spec = us.AuditSpec( kind="public_descent", public=["AGE_BAND", "SEX"], hidden=["AGE_BAND", "SEX", "OCC_MAJOR", "WKHP_BAND"], target="income_over_threshold", weight="sample_weight", candidate_refinements=["OCC_MAJOR", "WKHP_BAND"], q={"name": "bounded_shift", "radius": 0.5}, min_cell_weight=25, title="Income-Threshold Representation Audit", ) run = spec.run(rows_or_frame) print(run.to_markdown()) print(run.to_json()) print(run.to_tables().keys()) ``` The executed `AuditRun` keeps both the spec and report: ```python payload = run.as_dict() payload["spec"] payload["report"] ``` ## Supported Kinds Use `kind="public_descent"` for the standard report: ```python spec = us.AuditSpec( kind="public_descent", public=["segment"], hidden=["segment", "region", "tenure_band"], target="outcome_rate", q="saturated", ) ``` Use `kind="sensitivity"` for robustness grids: ```python spec = us.AuditSpec( kind="sensitivity", public=["segment"], hidden=["segment", "region", "tenure_band"], target="outcome_rate", q_presets=[ "saturated", {"name": "bounded_shift", "radius": 0.5}, "observed", ], min_cell_weights=[1, 10, 25], ) ``` Use `kind="frontier"` for public-representation search: ```python spec = us.AuditSpec( kind="frontier", public=["segment"], hidden=["segment", "region", "tenure_band", "channel"], target="outcome_rate", candidate_refinements=["region", "tenure_band", "channel"], q_presets=["saturated", {"name": "bounded_shift", "radius": 0.5}], ambiguity_limit=0.01, bucket_budget=40, search="beam", ) ``` Use `kind="certificate"` when the same search should produce a pass/fail representation-stability certificate: ```python spec = us.AuditSpec( kind="certificate", public=["segment"], hidden=["segment", "region", "tenure_band", "channel"], target="outcome_rate", candidate_refinements=["region", "tenure_band", "channel"], q_presets=["saturated", {"name": "bounded_shift", "radius": 0.5}], ambiguity_limit=0.01, bucket_budget=40, search="exhaustive", ) ``` Certificate specs require `ambiguity_limit`. By default, heuristic searches such as `greedy` or `beam` are marked inconclusive rather than passed; set `exact_required=False` when the certificate should cover only evaluated candidates. Frontier and certificate specs can also request experimental residopt screening for L2-budget stress tests: ```python spec = us.AuditSpec( kind="certificate", public=["segment"], hidden=["segment", "region", "tenure_band", "channel"], target="outcome_rate", candidate_refinements=["region", "tenure_band", "channel"], q_presets=[{"name": "l2_budget", "radius": 0.05}], ambiguity_limit=0.01, screening_backend="residopt", ) ``` The resulting frontier or certificate report records conservative endpoints, exact fallbacks, and avoided exact solves in Markdown and structured exports. `run_audit(...)` also accepts a plain mapping, which is useful when loading a spec from JSON or YAML: ```python run = us.run_audit(spec_mapping, rows_or_frame) ``` ## Q Presets Specs use serializable Q descriptions: ```python "saturated" {"name": "bounded_shift", "radius": 0.5} {"name": "tv_budget", "radius": 0.1, "backend": "cvxpy"} {"name": "tv_budget", "radius": 0.1, "backend": "cvxpy", "solver": "SCIP"} {"name": "fiber_support_floor", "solver": "SCIP", "settings": {"min_active": 2, "min_share": 0.1}} {"name": "observed"} ``` `solver_options` may also be supplied as a JSON object and are forwarded to `cvxpy.Problem.solve(...)` for CVXPY-backed presets. Preset-specific values that do not fit the standard `radius` or `cost` fields live under `settings`. For non-serializable custom environments, custom constraint builders, or plugin-specific runtime objects, call the lower-level Python APIs directly. ## Current Scope The first `AuditSpec` slice covers public-descent reports, sensitivity reports, and public-representation frontier search. Causal reporting suites, artifact directory writers, and plugin-specific spec extensions can build on the same shape without changing the report APIs.