Invariants¶
Compitum defends a set of invariants checked by tests and by runtime process signals:
Lyapunov-like energy drift does not increase under allowed updates.
Constraint residuals respect
A · x ≤ bwith documented slack.Metric coherence: neighborhoods act like neighborhoods in the SPD metric.
Boundary behavior: tie regions are observable with gap/entropy/uncertainty checks.
See the tests/invariants/ suite for details and run with pytest -m invariants.
Coverage (selected)¶
Geometry (SPD metric)
Ray monotonicity:
test_invariants_metric_ray.pyTriangle inequality:
test_invariants_metric_triangle.pyUpdate descent + SPD:
test_invariants_metric_update.pySPD eigenvalue bounds:
tests/metric/test_metric_spd_bounds.py
Coherence / OOD
Monotone outward:
test_invariants_coherence.pySymmetry (±v):
test_invariants_coherence_symmetry.pyDensity–distance coupling:
test_invariants_density_energy_coupling.pyScore directionality (finite diff):
test_invariants_coherence_score_dir.pyMixture discrimination:
tests/coherence/test_coherence_mixture_discrimination.py
Control / Lyapunov
Properties (bounds, monotonicity):
test_invariants_control_props.pySequences (ΔV non-increase/bounded, recovery):
test_invariants_control_sequences.py,test_invariants_control_lyapunov.py,test_invariants_control_deltaV_strong.py,test_invariants_control_combined_proxy.py
Constraints / Duals
Feasibility monotone in b:
test_invariants_constraints_monotone.pyDual sanity/monotone/near-binding:
test_invariants_constraints_duals.py,test_invariants_duals_monotone.py,test_invariants_duals_near_binding.pyDual scaling sanity:
tests/invariants/test_invariants_duals_scaling.pyArgmax stability:
test_invariants_solver_argmax.py
Router / Certificates
Determinism (repeated route):
test_invariants_router_determinism.pyParaphrase flip budget + explainability:
test_paraphrase_suite.py,test_paraphrase_explainability.pyJSON structure/schema:
tests/certificates/*.py
Run the fast suite:
pytest -q tests/invariants
Mutation-Hardening Coverage (Boundary & Edge-Case Invariants)¶
A separate category from the property-based suite above: exact-value and boundary-condition
invariants found via a real mutmut sweep across the full src/compitum shard matrix (20 files in
scope – the original 17 plus integrations/materials_project_audit.py,
applications/fusion/diiid_adapter.py, and applications/fusion/eval_offline.py; see
MUTATION_HARDENING_STATUS.md for per-file scores). Every release-critical module is now fully
classified, with only 2 accepted, documented defensive survivors remaining across the whole matrix
(constraints.py ID 62, metric.py ID 125). Each line below was a genuine survivor – an existing
test exercised the code path but didn’t pin down the exact value or boundary needed to actually kill
a behavioral mutation – confirmed against real code before the fix, and in energy.py’s case
confirmed killed against the real mutant diff.
effort_qp.py:e_starresolves to0.0(not1.0) exactly at thegrad == 0boundary; q1/t1/c1 multiplier terms are exercised with non-unity values;lambda_high’smax(0.0, grad)floor is exercised with0 < grad < 1, not justgrad > 1where a1.0floor mutation happens to be masked —tests/test_effort_qp.pycapabilities.py:Capabilities.deterministicdefaults toFalsewhen omitted —tests/test_capabilities.pyboundary.py:uncertaintydefaults to0.0(and correctly resolvesis_boundary=False) when the winning model is missing fromu_sigma; the realgap_thresholddefault (0.05) is exercised where a much-larger mutated default would flip the result (every other case either has a small gap or a failing sigma condition that masks it);entropy’s exact value is pinned (not just which side ofentropy_thresholdit lands on);gap < gap_threshold,entropy > entropy_threshold, andsigma > sigma_thresholdare each exercised at exact equality (not just clearly inside/outside), where a</>vs<=/>=mutation would otherwise survive —tests/test_boundary.pypredictors.py: isotonic calibration clips out-of-domain raw values to the boundary’s fittedyrather than extrapolating; each of the 3 internalGradientBoostingRegressors’ exactn_estimators/random_statehyperparameters;fitteddefaults toFalse, notNone(not xpasses for both) —tests/test_predictors.pycontrol.py: the EMA trust-region branch is neutral (no change) exactly at the 1.5x/0.7x thresholds, not just clearly above/below them;kappa/r0constructor defaults (0.1/1.0, never exercised since every other test passes them explicitly);eta_cap’s+1e-6epsilon is checked atgrad_norm=0.0, where it’s the entire denominator, not2.0, where it’s too small a relative perturbation for the default tolerance to catch —tests/test_control.pysymbolic.py:+,*,@operators evaluate correctly, not just-//;SymbolicValue.to_latexis genuinely@abstractmethod(direct instantiation raisesTypeError);TypeError/ValueErrormessages match their exact text, not just that some exception of that type was raised;__matmul__’s emptylatex_opandSymbolicMatrix.T’sf"{name}^T"label are both checked viato_latex()/.name, not just.evaluate()—tests/test_symbolic.pysecurity.py: SHA-256 outputs match the exact expected digest (not just length 64);is_offline()/redaction_enabled()default toFalsewhen unset;AuditRecord.commitdefaults toNone, not"";write_audit_recordcreates missing parent directories and its filename embeds a plausible current epoch-ms timestamp with exact 2-space JSON indentation;git_commit_short()resolves a real, well-formed commit hash from this repo’s own.gitstate (not silently swallowed toNone) —tests/security/test_security_utils.pyconstraints.py: shadow price matches the exact(Δutility)/1e-5value, not just its sign; multi-constraint infeasible fallback zeros everylambda_i; feasibility’sA@x <= b + 1e-10tolerance is exercised atA@xexactly equal tob + 1e-10(not justbitself, where the epsilon makes<=and<agree regardless); a competitor missing fromutilitiesstill loses in the shadow-price calculation specifically (-infdefault), not just inm_starselection (a separate line with the same default pattern); the relaxation epsilon’s sign (b_relaxed[i] += 1e-5) is exercised where the unrelaxed constraint passes by a margin under1e-5; the competitor-skip (continue, notbreak) and utility-tie boundary (>, not>=) are checked via a later competitor’s capability call actually happening, not just the resulting shadow price (which can coincidentally match either way);contextis passed through on every recorded capability call, not just at least one (an unmutated code path elsewhere already guarantees one correct-looking call regardless); a failed capability check keeps a competitor non-viable even though a separate, independent feasibility re-check happens right after it; the first (not last) qualifying competitor’s shadow price sticks —tests/test_constraints.py. A Hypothesis property test additionally sweepsselect()across random utility assignments and feasible/infeasiblexBvalues, checking invariants that must hold regardless of the specific numbers (returned model is always an input, shadow prices non-negative,m_staris the max-utility model when all models share equal viability).integrations/matbench_adapter.py: CSV columns map to the correct attribute values, not just present attributes;id_column/formula_column/label_columndefault toNone, not""(both falsy everywhere they’re checked); all 4 “column not found”/”missing columns” error messages match their exact full text, not just an unanchored substring (pytest.raises(match=)is a substring search, so text wrapped around the expected substring still “matches”) —tests/integrations/test_matbench_adapter.pycoherence.py:WeightedReservoirclamps nonpositive weights to1e-6;WeightedReservoir’s andCoherenceFunctional’skconstructor default is1000; reservoir replacement doesn’t fire when the sampled index equalskexactly (j < k, not<=); the fitted KDE’s bandwidth matches Scott’s rule exactly (n ** (-1/(d+4)));log_evidence/batch_log_evidenceclip to exactly[-10.0, 10.0](checked via a mocked KDE forcing extreme scores, since realistic fits never naturally exceed that range) —tests/test_coherence.pyenergy.py:comps["uncertainty"]/U_varmatch the exact variance formula (bothcompute()andbatch_compute()); debug/timing prints match their full exact (or regex-matched, elapsed-time bounded) content, not just a leading substring; evidence usesxR - model.center, not+, in bothcompute()andbatch_compute();costusesc + model.cost, not-, in both — every prior test used a zero center/zero cost, where the two are indistinguishable;batch_compute()’scomps_listdict is checked key-by-key (not just"quality");compute()’s debug-print gate (step % 100 == 0 and env == "1", checked before_stepincrements) is exercised at a nonzero multiple of 100 (not just0, where%//and%100/%101happen to agree) and with the env var unset at_step == 0(where anand->ormutation would print regardless) —tests/test_energy.py,tests/test_energy_debug_paths.py,tests/energy/test_symbolic_free_energy.pyrouter.py:update_stridefloors to1forstride <= 0and defaults to8when omitted;router.srmf is router.controller(legacy alias); disabled-controllerdrift_statusmatches the controller’s exact current state, not just key presence, in bothroute()andbatch_route();SwitchCertificate.to_json()truncatespgd_signatureto exactly 16 chars and indents with exactly 2 spaces;route()/batch_route()’sgrad_normplaceholder (1.0) andeta(1e-2) values are exact;batch_route()’s per-sample_stepaccumulates by exactly 1 (not reset, not doubled); its batch-level update gate fires at_step == _strideexactly (>=, not>); its per-model update loop usescontinue(notbreak) so an earlier never-selected model can’t block a later one’s real update;batch_route(prompts=None)defaults to empty-string prompts, not a placeholder; both route()’s and batch_route()’s debug-print elapsed times are bounded, not just regex-shaped (atime.time() + start_timesign flip still matches\d+\.\d{4}) —tests/test_router_simple.py,tests/test_router_batch.pymetric.py:_update_cholesky()’s error-recovery delta/prints are exact and the recoveredWis upper-triangular;distance()/batch_distance()’slen(whitened_residuals) > rankboundary is exercised at exact equality, andz = x - mu(not+ mu); theValueErrorwhenWstaysNonematches its exact message; the sigma-squared clamp floors at exactly0.0, not1.0(forced via a mocked indefinite covariance, since a real PSD one never goes negative);batch_update_spd()’sd_batch_safeepsilon,A_batch/grad_L/z_norm2_batch/lipschitz/eta_stabarithmetic, and the gradient-descent direction (- eta_eff * grad_L, not+) are all pinned to exact values; a wildly-skewed-magnitude batch forces the backtracking loop to genuinely engage (theeta_stab“stability cap” is only an average-based Lipschitz estimate, not worst-case), pinning itseta_eff *= 0.5/new_L = self.L - eta_eff * grad_Larithmetic; the loop’sbt-counter and itsbt < 8boundary (and thewhilecondition’s owne1 > e0re-check, distinct from the pre-loopif) are each pinned by batches engineered to need a specific, exact number of halvings to converge — controlled discretely via the batch’s sample count (more small “padding” samples alongside one large outlier shrinks the average-based Lipschitz estimate, requiring proportionally more halvings), landing precisely on the loop’s iteration-count boundaries;fnorm > 10.0’s clamp is exercised withfnormstrictly between 10 and 11 (not just at 10 exactly, where the clamp is a no-op regardless of>/>=); the residual-pruning loop removes from the front (FIFO), not an arbitrary index —tests/test_metric.py,tests/test_metric_debug_path.pypgd.py:RegexPromptExtractor.extract_features()’s ~40 feature-dict entries all match their exact computed value (one comprehensive golden-vector test on an engineered prompt), not just a loose>= 1.0/presence check that a dict-key-rename mutation could pass by coincidence (a missing key is silently backfilled with0.0, which a loose check can miss when the real value happens to also look “present enough”);syn_0/syn_1/sem_0/sem_1/sem_2’s empty-input fallbacks default to0.0; thelen(w) > 6“long word” boundary is exercised at exactly 6 characters;"class " in prompt or "def " in promptis exercised with each operand isolated (both, neither, and each alone) —tests/pgd/test_regex_prompt_extractor.pyintegrations/materials_project_audit.py:SRMFState.current_phase()’s three-way classification asserts exact"drift"/"constraint"labels (not just membership in a loose set) and is exercised at both tie boundaries (drift == bias,constraint == bias, each falling through to"bias") —tests/test_materials_project_audit.pyapplications/fusion/diiid_adapter.py:load_shot_csv()’s required-column check raises its exact message (not just a substring), the defaultstate_dimis exercised, Te_core/ne/q_min map into state columns 0/1/2 exactly (distinct per-column values catch swaps or renamed lookups), missing optional columns zero-fill, and the crash-index threshold (q_min < 1.0, first index only) is exercised at exact equality and with multiple below-threshold samples —tests/applications/test_diiid_adapter_options.pyapplications/fusion/eval_offline.py:lead_time_from_q_threshold()’s positive-lead-time arithmetic is pinned to its exact value (non-uniformtime_msspacing rules out a coincidental match), andcompute_alarm_series()’s first-alarm latch is proven to stay on the first alarming index rather than a later one, via a canned monitor replaying a fixed alarm/no-alarm sequence —tests/applications/test_fusion_offline_eval.py
Known true equivalent mutants (not gaps):
d_best = abs(-comps[...]["distance"])— appears 3 times (route()’s metric-update branch,route()’s controller branch,batch_route()’s per-sample loop) —abs(-x) == abs(x)for all realx, so no test can ever distinguish the two.router.py’sbatch_route()batch-level gateenable_metric_update and (_step >= _stride)mutated toor—update_datacan only be non-empty if the per-sample gate already fired, which (since_steponly increases) guarantees_step >= _strideis already true by then; the gate’s only other possible effect (skipping an already-guaranteed-empty pass) is unobservable since the per-model loop’s ownif not data: continuewould skip it anyway.flush=Trueonenergy.py’scompute()debug prints — every test captures stdout viaredirect_stdoutto an in-memory buffer, whereflushhas no observable effect on the captured text; distinguishing it would require asserting on real OS-level buffering, not this code’s logic.The unused default string in
security.py’sis_offline()/redaction_enabled()(os.environ.get(..., "0")) — both functions’ entire contract is== "1", so any non-"1"default produces the same result; the raw default string is never itself observable.security.py’sgit_commit_short():head.split(":", 1)vssplit(":", 2)— git forbids:in ref names, so a realHEAD(ref: refs/heads/<branch>) always contains exactly one:, makingmaxsplit=1andmaxsplit=2produce identical results against any real repository state.security.py’sgit_commit_short():errors="ignore"vserrors="XXignoreXX"on the HEAD/ref file reads — confirmed equivalent only after a real CI run showed it still surviving despite a test asserting a real non-Noneresult (seeMUTATION_HARDENING_STATUS.md’s real-CI correction note). Python’serrors=decode-error handler is only consulted when an actual decode error occurs; git’s HEAD/ref files are always clean ASCII, so they decode successfully regardless of what garbage stringerrors=holds.boundary.py’sprobs = np.exp(arr - u1)vsnp.exp(arr + u1)— the immediately-followingprobs /= probs.sum()normalization is invariant to any constant additive shift applied uniformly toarrbefore the exponential (softmax shift-invariance), andu1is a single scalar shared across every element ofarr. Only distinguishable via float overflow at utility magnitudes far outside this system’s realistic bounded range.coherence.py’ssample_weight=w / w.sum()vsw * w.sum()— sklearn’sKernelDensity.fitinternally renormalizessample_weightbefore use, so any positive scalar rescaling of the same weight vector produces identical results up to ~1e-15 floating-point noise (verified empirically, not assumed).metric.py’smetric_matrix(): thename=labels passed toSymbolicMatrix/SymbolicScalar("L","\delta","I") — the function returns only.evaluate()’s numpy array; the labeled objects (and theirto_latex()output) are local and discarded, never exposed to any caller.metric.py’s_update_cholesky()recovery delta’s upper clamp (min(..., 1e-1)vs1.1) — entering thatexceptblock at all requiresself.delta <= 0(any positive delta alone guaranteesL @ L.T + delta*Iis positive-definite, so Cholesky can never fail), and the recovery step only adds1e-3, so the result can never exceed0.1regardless of the mutation.metric.py’ssurrogate_energy’s0.5 *scaling constant vs1.5 *— its return value is only ever used ine1 > e0comparisons; scaling both sides by the same positive constant never changes which is larger, so it can’t affect control flow or any other observed value.metric.py’sbatch_update_spd()’sfnorm > 10.0vs>= 10.0— exactly atfnorm == 10.0, the clamp (self.L *= 10.0/fnorm) multiplies by exactly1.0, a no-op in IEEE754 regardless of whether it fires; the only point where>and>=disagree is also the only point where the clamp can’t have any effect.metric.py’sbatch_update_spd()’s pre-loopif e1 > e0:vs>=— the two conditions disagree only ate1 == e0exactly, but the only statement gated by thisifbefore thewhileloop isbt = 0(a local counter with no effect if the loop never iterates); the loop’s own re-check (bt < 8 and e1 > e0, unmutated) independently re-derives the identicale1 > e0from the same unchanged values, so at the one point of disagreement the loop still runs zero iterations either way, andself.Lends up bit-identical regardless of how theifwas entered.pgd.py’saux_*feature padding (loop bound, key-name mismatches between the write and the.get()read) —aux_*features are permanently0.0by construction (nothing else inextract_features()ever assigns them a nonzero value), and any genuinely-missing key gets backfilled with0.0anyway by the “ensure all keys present” safety loop, so no combination of these mutations can ever produce an observable difference.pgd.py’sprag_*Banach features’ defensive.get(key, default)reads — each is read back immediately after being unconditionally assigned the same value the.get()default uses, so renaming either the assignment’s key or the read’s key, or changing the read’s default, all fall through to a value that coincidentally equals what would have been produced anyway.applications/fusion/eval_offline.py’slead_time_from_q_threshold():alarm_idx >= crash_idxvs>— the two conditions disagree only whenalarm_idx == crash_idxexactly, but at that point the>variant falls through totime_ms[crash_idx] - time_ms[alarm_idx]with identical indices, which is always exactly0.0in IEEE754 — the same value the earlyreturn 0.0gives. Confirmed by direct simulation, not just inspection.