Skip to main content

CRUS-T: a normalized, programmatically computable runtime reliability score for agentic AI, per Ghosh Dastidar, 'Proportionate Governance in Practice'.

Project description

crust-score

A reference implementation of CRUS-T score: a normalized, programmatically computable runtime reliability score for agentic AI, from

Satyaki Ghosh Dastidar, Proportionate Governance in Practice: An IDEA–CRUS-T Framework for Risk-Tiered, Runtime-Governed AI Systems in Financial Services. Preprint, 2026.

CRUS-T scores an AI capability or execution trajectory on four dimensions — Consistency, Robustness, Uncertainty awareness, and Safety — each built from three standard, auditable sub-metrics, aggregated with a collapse-sensitive weighted geometric mean, and gated on a conservative statistical bound rather than a point estimate. Safety additionally carries a discontinuous hard gate: a single critical policy violation zeroes the governed safety score regardless of the continuous score, so it can never be averaged away.

This library implements the score itself (Section 5 of the paper) plus a thin tier-gating layer on top of it (Section 5.6–5.7) that decides continue/escalate/contain against a threshold vector you supply. It does not implement the paper's separate five-dimension risk-tiering method (Section 4 — Authority/Impact/Agency/Exposure/Recoverability → control tier); that assigns a design-time control tier, whereas this library is about the runtime reliability score that verifies a tier's assumptions continue to hold in production.

Status

Early (0.1.0). The math is unit-tested against the paper's equations and against the worked example in Appendix C. The weights, tolerances, and thresholds you configure are governance parameters, not statistical defaults — see Governance parameters below before using this for anything with real consequence.

Install

pip install -e .          # from a local checkout
pip install -e ".[dev]"   # + pytest, for running the test suite

Requires Python 3.10+. No required runtime dependencies.

How the code maps to the paper

Paper section Module
5.1 Design principles and normalization primitives crus_t.primitives
5.2 Consistency (C1/C2/C3) crus_t.metrics.consistency
5.3 Robustness (R1/R2/R3) crus_t.metrics.robustness
5.4 Uncertainty awareness (U1/U2/U3) crus_t.metrics.uncertainty
5.5 Safety (S1/S2/S3) + critical-violation hard gate crus_t.metrics.safety
Eqs. 8/12/16/20-21 — dimension aggregation crus_t.dimensions
Eq. 22 — composite score crus_t.score
Eq. 24 — bootstrap lower-confidence-bound gating crus_t.bootstrap
5.6-5.7 — tier gate, runtime zones (continue/escalate/contain) crus_t.gating
Per-run scoring crus_t.run
Rolling many runs up into a batch/portfolio view crus_t.aggregate
Governance-owned weights/tolerances crus_t.config

Every public function's docstring cites the specific equation it implements, so you can go from a number in the paper straight to the code that produces it (and back).

What this library does not do for you

Several CRUS-T sub-metrics depend on a learned component the paper deliberately keeps out of the governed math: an entailment model for groundedness (S1), an embedding or entailment model for semantic similarity (C1/C2), a task-quality function Q(.) for Robustness. This library takes the outputs of those components (an entailment boolean, a similarity score, a quality score) as plain function arguments — it does not call any model itself. Section 5.5 of the paper is explicit about why: "a probabilistic verifier operating in the same semantic space as the system it polices is architecturally blind to fluent-but-wrong outputs," so whatever model you plug in needs to be validated and governed separately, on its own precision/recall for the violation class it's detecting.

Quickstart

from crus_t import (
    compute_consistency, compute_robustness, compute_uncertainty,
    governed_safety, PolicyObservation, safety_to_dimension_score,
    ReliabilityVector, composite,
    ThresholdVector, evaluate_gate,
    make_run_score, aggregate_run_scores,
)

# 1. Compute each dimension from its three sub-metrics (already observed
#    from your evaluation harness / production telemetry).
c = compute_consistency(c1=0.94, c2=0.88, c3=0.97)
r = compute_robustness(r1=0.85, r2=0.96, r3=0.80)
u = compute_uncertainty(u1=0.89, u2=0.81, u3=0.85)

safety_result = governed_safety(
    entailed_claims=98, total_claims=100,
    policy_observations=[PolicyObservation("no_stale_citation", severity=1.0, violation_count=0)],
    n_trajectories=100,
    authorized_calls=10, total_external_calls=10,
    critical_violation_observed=False,
    tau_safety=0.10,
)
s = safety_to_dimension_score(safety_result)

vector = ReliabilityVector(c, r, u, s)
print(vector.as_dict())          # {"C": 0.93, "R": 0.87, "U": 0.85, "S": ...}
print(composite(vector))         # single reporting number, Eq. (22)

# 2. Package it as a run and gate it against a tier's thresholds. Threshold
#    values are always your own governance input -- this library has no
#    built-in per-tier table.
thresholds = ThresholdVector(consistency=0.80, robustness=0.75, uncertainty=0.78, safety=0.90)
gate = evaluate_gate(vector.as_dict(), thresholds)
run = make_run_score(run_id="run-001", capability_id="drafting", vector=vector, gate=gate)
print(gate.zone)                 # RuntimeZone.CONTINUE / ESCALATE / CONTAIN

# 3. Later, roll many runs up into a batch view.
agg = aggregate_run_scores([run, ...])
print(agg.escalation_rate, agg.containment_rate, agg.axis_summaries["safety"].mean)

For a regulatory-grade decision, gate on a bootstrap lower bound instead of the point estimate (Eq. 24):

from crus_t import bootstrap_lower_bound

# `statistic` recomputes a dimension score from a resampled item list --
# wire this to your own evaluation-set records.
result = bootstrap_lower_bound(evaluation_items, statistic=my_dimension_statistic, seed=42)
gate = evaluate_gate({"C": result.lower_bound, ...}, thresholds)

See examples/worked_example.py for a runnable version of Appendix C's Drafting-capability example, and examples/quickstart.py for the snippet above.

Governance parameters

Every tolerance (tau), every sub-metric weight, every threshold vector, and the bootstrap confidence level are, per Section 5.1 of the paper, governance parameters: "set by the second line of defense from pooled validation evidence, versioned, and subject to challenge — not free parameters tuned to produce a desired outcome." crus_t.config.GovernanceConfig gives them one explicit, serializable home; ThresholdVector in crus_t.gating is a plain, explicit input with no built-in defaults. This library will not stop you from tuning a threshold until a report looks good — that governance discipline lives with your process, not the code.

Development

pip install -e ".[dev]"
pytest                 # run the test suite
pytest --cov=crus_t    # with coverage

License

MIT. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

crust_score-0.1.0.tar.gz (38.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

crust_score-0.1.0-py3-none-any.whl (34.4 kB view details)

Uploaded Python 3

File details

Details for the file crust_score-0.1.0.tar.gz.

File metadata

  • Download URL: crust_score-0.1.0.tar.gz
  • Upload date:
  • Size: 38.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for crust_score-0.1.0.tar.gz
Algorithm Hash digest
SHA256 b63df06550c53dfacf16174449d98f0cec80c04cbdcac9590d4ed45104c312fa
MD5 30cec3e0dcb7c02d060eb45e678ae69f
BLAKE2b-256 52ba2e6ffc6b9e38da22dc93d44f80d42d51b90f4874926d5acf333e9d578938

See more details on using hashes here.

Provenance

The following attestation bundles were made for crust_score-0.1.0.tar.gz:

Publisher: publish.yml on satyakigd/crust

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file crust_score-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: crust_score-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 34.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for crust_score-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 30af218539e1d67d5c9d28c1ea143cdfa500186679d5de1b8984bd37dacf49a0
MD5 38b0923da79a46f50ea41820bf31e27d
BLAKE2b-256 522080f6cbcfd3e49f36654dbb0c65e69ddd6121cfd66d7a578bd24567927154

See more details on using hashes here.

Provenance

The following attestation bundles were made for crust_score-0.1.0-py3-none-any.whl:

Publisher: publish.yml on satyakigd/crust

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page