riskgate 1.0.0rc3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. riskgate-1.0.0rc3/LICENSE +202 -0
  2. riskgate-1.0.0rc3/PKG-INFO +338 -0
  3. riskgate-1.0.0rc3/README.md +284 -0
  4. riskgate-1.0.0rc3/pyproject.toml +80 -0
  5. riskgate-1.0.0rc3/riskgate/__init__.py +29 -0
  6. riskgate-1.0.0rc3/riskgate/adapters/__init__.py +48 -0
  7. riskgate-1.0.0rc3/riskgate/adapters/frameworks.py +415 -0
  8. riskgate-1.0.0rc3/riskgate/adapters/mcp_proxy.py +239 -0
  9. riskgate-1.0.0rc3/riskgate/adapters/openai_agents.py +175 -0
  10. riskgate-1.0.0rc3/riskgate/adapters/tool.py +97 -0
  11. riskgate-1.0.0rc3/riskgate/audit.py +77 -0
  12. riskgate-1.0.0rc3/riskgate/cli.py +172 -0
  13. riskgate-1.0.0rc3/riskgate/config.py +181 -0
  14. riskgate-1.0.0rc3/riskgate/conformal.py +98 -0
  15. riskgate-1.0.0rc3/riskgate/doers.py +69 -0
  16. riskgate-1.0.0rc3/riskgate/gate.py +889 -0
  17. riskgate-1.0.0rc3/riskgate/monitor.py +147 -0
  18. riskgate-1.0.0rc3/riskgate/multirisk.py +266 -0
  19. riskgate-1.0.0rc3/riskgate/provenance.py +206 -0
  20. riskgate-1.0.0rc3/riskgate/py.typed +0 -0
  21. riskgate-1.0.0rc3/riskgate/replay.py +182 -0
  22. riskgate-1.0.0rc3/riskgate/rules.py +86 -0
  23. riskgate-1.0.0rc3/riskgate/spec.py +163 -0
  24. riskgate-1.0.0rc3/riskgate/stl.py +492 -0
  25. riskgate-1.0.0rc3/riskgate/telemetry.py +67 -0
  26. riskgate-1.0.0rc3/riskgate/types.py +205 -0
  27. riskgate-1.0.0rc3/riskgate/weighted.py +175 -0
  28. riskgate-1.0.0rc3/riskgate/worlds.py +237 -0
  29. riskgate-1.0.0rc3/riskgate.egg-info/PKG-INFO +338 -0
  30. riskgate-1.0.0rc3/riskgate.egg-info/SOURCES.txt +42 -0
  31. riskgate-1.0.0rc3/riskgate.egg-info/dependency_links.txt +1 -0
  32. riskgate-1.0.0rc3/riskgate.egg-info/entry_points.txt +2 -0
  33. riskgate-1.0.0rc3/riskgate.egg-info/requires.txt +35 -0
  34. riskgate-1.0.0rc3/riskgate.egg-info/top_level.txt +1 -0
  35. riskgate-1.0.0rc3/setup.cfg +4 -0
  36. riskgate-1.0.0rc3/tests/test_core.py +197 -0
  37. riskgate-1.0.0rc3/tests/test_examples.py +45 -0
  38. riskgate-1.0.0rc3/tests/test_features.py +578 -0
  39. riskgate-1.0.0rc3/tests/test_groups.py +119 -0
  40. riskgate-1.0.0rc3/tests/test_multirisk.py +187 -0
  41. riskgate-1.0.0rc3/tests/test_stl.py +342 -0
  42. riskgate-1.0.0rc3/tests/test_use_case_kits.py +303 -0
  43. riskgate-1.0.0rc3/tests/test_warnings.py +62 -0
  44. riskgate-1.0.0rc3/tests/test_weighted.py +129 -0
@@ -0,0 +1,202 @@
1
+
2
+ Apache License
3
+ Version 2.0, January 2004
4
+ http://www.apache.org/licenses/
5
+
6
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7
+
8
+ 1. Definitions.
9
+
10
+ "License" shall mean the terms and conditions for use, reproduction,
11
+ and distribution as defined by Sections 1 through 9 of this document.
12
+
13
+ "Licensor" shall mean the copyright owner or entity authorized by
14
+ the copyright owner that is granting the License.
15
+
16
+ "Legal Entity" shall mean the union of the acting entity and all
17
+ other entities that control, are controlled by, or are under common
18
+ control with that entity. For the purposes of this definition,
19
+ "control" means (i) the power, direct or indirect, to cause the
20
+ direction or management of such entity, whether by contract or
21
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
22
+ outstanding shares, or (iii) beneficial ownership of such entity.
23
+
24
+ "You" (or "Your") shall mean an individual or Legal Entity
25
+ exercising permissions granted by this License.
26
+
27
+ "Source" form shall mean the preferred form for making modifications,
28
+ including but not limited to software source code, documentation
29
+ source, and configuration files.
30
+
31
+ "Object" form shall mean any form resulting from mechanical
32
+ transformation or translation of a Source form, including but
33
+ not limited to compiled object code, generated documentation,
34
+ and conversions to other media types.
35
+
36
+ "Work" shall mean the work of authorship, whether in Source or
37
+ Object form, made available under the License, as indicated by a
38
+ copyright notice that is included in or attached to the work
39
+ (an example is provided in the Appendix below).
40
+
41
+ "Derivative Works" shall mean any work, whether in Source or Object
42
+ form, that is based on (or derived from) the Work and for which the
43
+ editorial revisions, annotations, elaborations, or other modifications
44
+ represent, as a whole, an original work of authorship. For the purposes
45
+ of this License, Derivative Works shall not include works that remain
46
+ separable from, or merely link (or bind by name) to the interfaces of,
47
+ the Work and Derivative Works thereof.
48
+
49
+ "Contribution" shall mean any work of authorship, including
50
+ the original version of the Work and any modifications or additions
51
+ to that Work or Derivative Works thereof, that is intentionally
52
+ submitted to Licensor for inclusion in the Work by the copyright owner
53
+ or by an individual or Legal Entity authorized to submit on behalf of
54
+ the copyright owner. For the purposes of this definition, "submitted"
55
+ means any form of electronic, verbal, or written communication sent
56
+ to the Licensor or its representatives, including but not limited to
57
+ communication on electronic mailing lists, source code control systems,
58
+ and issue tracking systems that are managed by, or on behalf of, the
59
+ Licensor for the purpose of discussing and improving the Work, but
60
+ excluding communication that is conspicuously marked or otherwise
61
+ designated in writing by the copyright owner as "Not a Contribution."
62
+
63
+ "Contributor" shall mean Licensor and any individual or Legal Entity
64
+ on behalf of whom a Contribution has been received by Licensor and
65
+ subsequently incorporated within the Work.
66
+
67
+ 2. Grant of Copyright License. Subject to the terms and conditions of
68
+ this License, each Contributor hereby grants to You a perpetual,
69
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70
+ copyright license to reproduce, prepare Derivative Works of,
71
+ publicly display, publicly perform, sublicense, and distribute the
72
+ Work and such Derivative Works in Source or Object form.
73
+
74
+ 3. Grant of Patent License. Subject to the terms and conditions of
75
+ this License, each Contributor hereby grants to You a perpetual,
76
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77
+ (except as stated in this section) patent license to make, have made,
78
+ use, offer to sell, sell, import, and otherwise transfer the Work,
79
+ where such license applies only to those patent claims licensable
80
+ by such Contributor that are necessarily infringed by their
81
+ Contribution(s) alone or by combination of their Contribution(s)
82
+ with the Work to which such Contribution(s) was submitted. If You
83
+ institute patent litigation against any entity (including a
84
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
85
+ or a Contribution incorporated within the Work constitutes direct
86
+ or contributory patent infringement, then any patent licenses
87
+ granted to You under this License for that Work shall terminate
88
+ as of the date such litigation is filed.
89
+
90
+ 4. Redistribution. You may reproduce and distribute copies of the
91
+ Work or Derivative Works thereof in any medium, with or without
92
+ modifications, and in Source or Object form, provided that You
93
+ meet the following conditions:
94
+
95
+ (a) You must give any other recipients of the Work or
96
+ Derivative Works a copy of this License; and
97
+
98
+ (b) You must cause any modified files to carry prominent notices
99
+ stating that You changed the files; and
100
+
101
+ (c) You must retain, in the Source form of any Derivative Works
102
+ that You distribute, all copyright, patent, trademark, and
103
+ attribution notices from the Source form of the Work,
104
+ excluding those notices that do not pertain to any part of
105
+ the Derivative Works; and
106
+
107
+ (d) If the Work includes a "NOTICE" text file as part of its
108
+ distribution, then any Derivative Works that You distribute must
109
+ include a readable copy of the attribution notices contained
110
+ within such NOTICE file, excluding those notices that do not
111
+ pertain to any part of the Derivative Works, in at least one
112
+ of the following places: within a NOTICE text file distributed
113
+ as part of the Derivative Works; within the Source form or
114
+ documentation, if provided along with the Derivative Works; or,
115
+ within a display generated by the Derivative Works, if and
116
+ wherever such third-party notices normally appear. The contents
117
+ of the NOTICE file are for informational purposes only and
118
+ do not modify the License. You may add Your own attribution
119
+ notices within Derivative Works that You distribute, alongside
120
+ or as an addendum to the NOTICE text from the Work, provided
121
+ that such additional attribution notices cannot be construed
122
+ as modifying the License.
123
+
124
+ You may add Your own copyright statement to Your modifications and
125
+ may provide additional or different license terms and conditions
126
+ for use, reproduction, or distribution of Your modifications, or
127
+ for any such Derivative Works as a whole, provided Your use,
128
+ reproduction, and distribution of the Work otherwise complies with
129
+ the conditions stated in this License.
130
+
131
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
132
+ any Contribution intentionally submitted for inclusion in the Work
133
+ by You to the Licensor shall be under the terms and conditions of
134
+ this License, without any additional terms or conditions.
135
+ Notwithstanding the above, nothing herein shall supersede or modify
136
+ the terms of any separate license agreement you may have executed
137
+ with Licensor regarding such Contributions.
138
+
139
+ 6. Trademarks. This License does not grant permission to use the trade
140
+ names, trademarks, service marks, or product names of the Licensor,
141
+ except as required for reasonable and customary use in describing the
142
+ origin of the Work and reproducing the content of the NOTICE file.
143
+
144
+ 7. Disclaimer of Warranty. Unless required by applicable law or
145
+ agreed to in writing, Licensor provides the Work (and each
146
+ Contributor provides its Contributions) on an "AS IS" BASIS,
147
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148
+ implied, including, without limitation, any warranties or conditions
149
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150
+ PARTICULAR PURPOSE. You are solely responsible for determining the
151
+ appropriateness of using or redistributing the Work and assume any
152
+ risks associated with Your exercise of permissions under this License.
153
+
154
+ 8. Limitation of Liability. In no event and under no legal theory,
155
+ whether in tort (including negligence), contract, or otherwise,
156
+ unless required by applicable law (such as deliberate and grossly
157
+ negligent acts) or agreed to in writing, shall any Contributor be
158
+ liable to You for damages, including any direct, indirect, special,
159
+ incidental, or consequential damages of any character arising as a
160
+ result of this License or out of the use or inability to use the
161
+ Work (including but not limited to damages for loss of goodwill,
162
+ work stoppage, computer failure or malfunction, or any and all
163
+ other commercial damages or losses), even if such Contributor
164
+ has been advised of the possibility of such damages.
165
+
166
+ 9. Accepting Warranty or Additional Liability. While redistributing
167
+ the Work or Derivative Works thereof, You may choose to offer,
168
+ and charge a fee for, acceptance of support, warranty, indemnity,
169
+ or other liability obligations and/or rights consistent with this
170
+ License. However, in accepting such obligations, You may act only
171
+ on Your own behalf and on Your sole responsibility, not on behalf
172
+ of any other Contributor, and only if You agree to indemnify,
173
+ defend, and hold each Contributor harmless for any liability
174
+ incurred by, or claims asserted against, such Contributor by reason
175
+ of your accepting any such warranty or additional liability.
176
+
177
+ END OF TERMS AND CONDITIONS
178
+
179
+ APPENDIX: How to apply the Apache License to your work.
180
+
181
+ To apply the Apache License to your work, attach the following
182
+ boilerplate notice, with the fields enclosed by brackets "[]"
183
+ replaced with your own identifying information. (Don't include
184
+ the brackets!) The text should be enclosed in the appropriate
185
+ comment syntax for the file format. We also recommend that a
186
+ file or class name and description of purpose be included on the
187
+ same "printed page" as the copyright notice for easier
188
+ identification within third-party archives.
189
+
190
+ Copyright [yyyy] [name of copyright owner]
191
+
192
+ Licensed under the Apache License, Version 2.0 (the "License");
193
+ you may not use this file except in compliance with the License.
194
+ You may obtain a copy of the License at
195
+
196
+ http://www.apache.org/licenses/LICENSE-2.0
197
+
198
+ Unless required by applicable law or agreed to in writing, software
199
+ distributed under the License is distributed on an "AS IS" BASIS,
200
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201
+ See the License for the specific language governing permissions and
202
+ limitations under the License.
@@ -0,0 +1,338 @@
1
+ Metadata-Version: 2.4
2
+ Name: riskgate
3
+ Version: 1.0.0rc3
4
+ Summary: Certify, reject or ask: distribution-free risk control for the actions of LLM agents
5
+ Author-email: Saurabh Gupta <saurabhgupta3012@gmail.com>
6
+ License-Expression: Apache-2.0
7
+ Project-URL: Homepage, https://github.com/reallysaurabh/riskgate
8
+ Project-URL: Repository, https://github.com/reallysaurabh/riskgate
9
+ Project-URL: Documentation, https://github.com/reallysaurabh/riskgate/tree/main/docs
10
+ Project-URL: Changelog, https://github.com/reallysaurabh/riskgate/blob/main/CHANGELOG.md
11
+ Project-URL: Issues, https://github.com/reallysaurabh/riskgate/issues
12
+ Keywords: llm,agents,ai agents,tool calling,guardrails,agent safety,prompt injection,mcp,conformal prediction,conformal risk control,risk control,safety,digital twin
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
23
+ Classifier: Typing :: Typed
24
+ Requires-Python: >=3.10
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Requires-Dist: numpy>=1.24
28
+ Provides-Extra: dev
29
+ Requires-Dist: pytest>=7; extra == "dev"
30
+ Requires-Dist: matplotlib>=3.7; extra == "dev"
31
+ Requires-Dist: ruff>=0.5; extra == "dev"
32
+ Requires-Dist: mypy>=1.10; extra == "dev"
33
+ Provides-Extra: examples
34
+ Requires-Dist: matplotlib>=3.7; extra == "examples"
35
+ Provides-Extra: yaml
36
+ Requires-Dist: pyyaml>=6; extra == "yaml"
37
+ Provides-Extra: otel
38
+ Requires-Dist: opentelemetry-api>=1.20; extra == "otel"
39
+ Requires-Dist: opentelemetry-sdk>=1.20; extra == "otel"
40
+ Provides-Extra: mcp
41
+ Requires-Dist: mcp<3,>=2.3; extra == "mcp"
42
+ Provides-Extra: langgraph
43
+ Requires-Dist: langgraph>=1.2; extra == "langgraph"
44
+ Requires-Dist: langgraph-prebuilt>=1.1; extra == "langgraph"
45
+ Requires-Dist: langchain-core>=1.6; extra == "langgraph"
46
+ Provides-Extra: adk
47
+ Requires-Dist: google-adk>=2.11; extra == "adk"
48
+ Provides-Extra: openai-agents
49
+ Requires-Dist: openai-agents>=0.23; extra == "openai-agents"
50
+ Provides-Extra: docs
51
+ Requires-Dist: mkdocs-material>=9.5; extra == "docs"
52
+ Requires-Dist: markdown-callouts>=0.4; extra == "docs"
53
+ Dynamic: license-file
54
+
55
+ # riskgate
56
+
57
+ **Certify, reject, probe or ask: calibrated, consequence-aware checks for the actions of LLM agents.**
58
+
59
+ `riskgate` sits between an AI agent and its tools. Before a consequential action runs (scaling a service, issuing
60
+ a refund, changing a reactor setpoint) it predicts what the action would do under **every explanation of the
61
+ current situation that the evidence cannot rule out**. It lets the action through only if the worst plausible
62
+ outcome clears a safety threshold that has been **calibrated on labelled outcomes**, so that unsafe actions get
63
+ through at most a chosen fraction α of the time, *whatever the quality of your simulator*.
64
+
65
+ ```text
66
+ agent proposes ──► riskgate ──► CERTIFY → the tool runs
67
+ │ ├──► REJECT → "unsafe under every explanation; binding constraint: p95 latency" → agent re-plans
68
+ │ ├──► PROBE → "first run pg_stat_statements: it tells the two likely causes apart"
69
+ │ └──► ASK → a human decides, with the gate's explanation
70
+ └── no LLM on this path · fail-closed · every decision is logged and fingerprinted
71
+ ```
72
+
73
+ > **Status: 1.0.0rc3 (release candidate), Apache-2.0.** Everything below runs locally and is tested. The three example
74
+ > domains are **simulated** with scripted (LLM-like) agents. In addition, [`benchmarks/`](https://github.com/reallysaurabh/riskgate/tree/main/benchmarks/) replays **public
75
+ > logs of real LLM agents** offline: τ²-bench with eight 2026 frontier models, AgentDojo prompt-injection runs of 28
76
+ > model/defence pipelines, and ITBench. It also covers public telemetry and plant data (RCAEval, Tennessee Eastman).
77
+ > The calibrated bound held for all 40 agent configurations replayed; see [Results on real agents](https://github.com/reallysaurabh/riskgate#results-on-real-agents-public-benchmarks).
78
+ > The paper is under submission (see [Project status](https://github.com/reallysaurabh/riskgate#project-status)).
79
+
80
+ ---
81
+
82
+ ## In one minute (no jargon)
83
+
84
+ Imagine a new assistant on a night shift. Alarms go off, and the assistant wants to press a button.
85
+
86
+ - A **careless** assistant presses the button that fits its first guess.
87
+ - A **rule-following** assistant checks a list of forbidden buttons. The list knows nothing about tonight.
88
+ - A **careful** assistant asks: *"What could be going on? What would this button do in each case? Is it safe in all
89
+ of them?"* If yes, it presses. If it is clearly a bad idea, it says why. If it cannot tell, it first does a
90
+ harmless check (looks at a second gauge) or calls the supervisor.
91
+
92
+ `riskgate` is the careful assistant, built as software. And it keeps score: it has been tested on hundreds of past
93
+ or simulated situations, so it can say *"when I say 'safe', I am wrong at most 5% of the time"*, and it says
94
+ *"I don't know"* when a situation looks unlike anything it was tested on.
95
+
96
+ ## What it is (for engineers)
97
+
98
+ | You provide | Example | riskgate does |
99
+ |---|---|---|
100
+ | a **consequence model** `predict(action, hypothesis, context)` | digital twin, queueing model, `--dry-run`, DB savepoint + rollback | evaluates every candidate under every plausible hypothesis |
101
+ | a **hypothesis provider** `hypotheses(context)` (scored) | fault diagnoser, incident classifier, intent parser | keeps the calibrated *plausible set* (true cause retained with prob. ≥ 1 − δ) |
102
+ | a **spec** of signed margins | `Upper("p95_ms", 800)`, `Envelope("T", 340, 362)`, STL formulas | robust score = worst margin over plausible hypotheses |
103
+ | **labelled episodes** | simulated incidents, sandbox replays, audited postmortems | conformal risk control picks the threshold λ̂ with E[unsafe certified] ≤ α |
104
+ | optional **hard rules**, **probes** | "refunds > $500 need approval", read-only diagnostics | rules run first; probes are chosen to resolve the disagreement between hypotheses |
105
+
106
+ Numpy is the only runtime dependency. The certify path never calls an LLM, and anything unexpected (exceptions,
107
+ timeouts, missing or stale calibration, a failing audit sink) produces `ASK`, never `CERTIFY`.
108
+
109
+ ## Install
110
+
111
+ ```bash
112
+ pip install --pre riskgate # release candidate; extras: yaml, otel, mcp, langgraph, adk, openai-agents
113
+ pip install -e ".[dev]" # from a clone
114
+ ```
115
+
116
+ Python ≥ 3.10. [PyPI](https://pypi.org/project/riskgate/) · [GitHub](https://github.com/reallysaurabh/riskgate) (a ⭐ helps others find it).
117
+
118
+ ## Thirty-second example
119
+
120
+ ```python
121
+ import riskgate as rg
122
+
123
+ class TankModel: # consequence model: what would the action do?
124
+ version = "tank-model-v1" # bump on every change: old calibrations become VOID
125
+ def predict(self, action, hyp, ctx):
126
+ return {"level": ctx["level"] + action.args["v"] - hyp.params["leak"]}
127
+
128
+ class LeakDiagnoser: # hypotheses: what could be going on? (lower score = better fit)
129
+ version = "leak-diag-v1"
130
+ def hypotheses(self, ctx):
131
+ return [rg.Hypothesis(f"leak={l}", family=f"leak{l}", params={"leak": l},
132
+ score=abs(ctx["flow"] - l) / 8) for l in (0, 15, 30)]
133
+
134
+ gate = rg.Gate(TankModel(), rg.Spec(rg.Envelope("level", lo=10, hi=100, scale=10)), LeakDiagnoser(), alpha=0.05,
135
+ doer_id="tank-agent:v1") # the agent whose proposals you calibrate on: swapping it voids the calibration
136
+ gate.calibrate(labelled_episodes) # sets tau and lambda-hat; status -> VALID
137
+
138
+ d = gate.check(rg.Action("add", {"v": 40}), {"level": 80, "flow": 15.0})
139
+ print(d.verdict, d.reason) # ASK: cannot certify: best robust margin -2.000 < threshold -1.763 ...
140
+
141
+ @rg.guard(gate, context=read_tank_state) # or guard any tool function your agent framework calls
142
+ def add(v: float) -> str: ...
143
+ ```
144
+
145
+ The complete, runnable version (with episode generation) is [`examples/quickstart.py`](https://github.com/reallysaurabh/riskgate/blob/main/examples/quickstart.py).
146
+ The production-like lifecycle (calibrate → sign → deploy → outcomes → drift → recalibrate) is
147
+ [`examples/end_to_end_sre.py`](https://github.com/reallysaurabh/riskgate/blob/main/examples/end_to_end_sre.py), explained step by step in
148
+ [docs/end_to_end.md](https://github.com/reallysaurabh/riskgate/blob/main/docs/end_to_end.md).
149
+
150
+ ## How a decision is made
151
+
152
+ ```mermaid
153
+ flowchart LR
154
+ A["agent: ranked tool calls"] --> R{"hard rules"}
155
+ R -->|blocked| REJ1["REJECT / ASK"]
156
+ R --> H["plausible hypotheses<br/>score <= tau"]
157
+ H -->|"unfamiliar evidence"| ASK0["ASK"]
158
+ H --> M["consequence model:<br/>margin m(a, h) for each pair"]
159
+ M --> S["robust score<br/>s(a) = min over h"]
160
+ S -->|"first a with s(a) >= lambda-hat"| C["CERTIFY"]
161
+ S -->|"hypotheses disagree,<br/>a probe can tell"| P["PROBE, then re-check"]
162
+ S -->|"unsafe under every h"| REJ["REJECT + reason"]
163
+ S -->|otherwise| ASK["ASK a human"]
164
+ ```
165
+
166
+ Every decision carries a **guarantee status**: `VALID` (calibrated, components unchanged, no drift), `DEGRADED`
167
+ (the drift monitor fired: the threshold may only tighten until you recalibrate) or `VOID` (no calibration, or the
168
+ model, spec, rules, probes or agent changed since calibration: every check returns `ASK`).
169
+
170
+ ## What is guaranteed, and what is not
171
+
172
+ For exchangeable episodes and unchanged components:
173
+
174
+ | Mode | Guarantee |
175
+ |---|---|
176
+ | `policy` (default) | P(the action your agent executes is unsafe) ≤ α, for the agent you calibrated with (`doer_id` is fingerprinted) |
177
+ | `agnostic` | the same bound for **any** agent that executes only certified actions, even after you swap the LLM |
178
+ | `guarantee="high_probability"` | P(risk of *this* calibrated gate ≤ α) ≥ 1 − δ (Learn-then-Test), instead of on average |
179
+ | two-stage probing | probe harm + unsafe execution after the probe, in total ≤ α |
180
+
181
+ Not guaranteed: per-situation (conditional) risk; validity under arbitrary distribution shift (the drift monitor
182
+ detects it, the threshold only tightens, and you recalibrate); multi-step closed-loop behaviour; wrong labels.
183
+ A bad consequence model costs **efficiency** (more `ASK`s), not validity. Details:
184
+ [docs/calibration.md](https://github.com/reallysaurabh/riskgate/blob/main/docs/calibration.md).
185
+
186
+ ## Use cases
187
+
188
+ Building blocks for the decisions on the [RiskGate site](https://github.com/reallysaurabh/riskgate/blob/main/docs/use_cases.md), each with a runnable, simulated example in
189
+ [`examples/use_cases/`](https://github.com/reallysaurabh/riskgate/tree/main/examples/use_cases/):
190
+
191
+ | Module | For | Example |
192
+ |---|---|---|
193
+ | `rg.DiscreteWorlds`, `rg.OutcomeTable` | one hidden fact with a few values: paid or failed, already refunded, a hold or fraud, dormant or scheduled | `payments_upi.py`, `missing_item_refund.py`, `card_dispute.py`, `idle_vm_cleanup.py` |
194
+ | `riskgate.provenance` | instructions planted in files, e-mails and web pages (prompt injection) | `prompt_injection.py` |
195
+ | `rg.replay`, `rg.resplit`, `rg.sweep` | run labelled history through a gate; validity over re-splits; the error budget as a dial | all of them |
196
+ | `riskgate.rules` | `needs_person`, `never`, `amount_above`, `irreversible` | `card_dispute.py`, `payments_upi.py` |
197
+
198
+ ```python
199
+ table = rg.OutcomeTable({"confirm_order": ["paid_late"], "reply_auto_reversal": ["failed"], "issue_refund": ["paid_twice"]},
200
+ reveals={"check_txn_status": {"paid_late": "SUCCESS", "failed": "FAILED", "pending": "PENDING",
201
+ "paid_twice": "DUPLICATE"}})
202
+ gate = rg.Gate(table, table.spec, worlds, probes=table.probes(), noop=table.noop, min_separation=table.separation / 2,
203
+ doer_id="support-bot:v1")
204
+ gate.calibrate(history)
205
+ print(rg.replay(gate, held_out)) # unsafe 1.5% (agent alone 88.8%) · autonomous 79.8% · asked 20.2% · probed first 72.7%
206
+ ```
207
+
208
+ ## Works with your agent framework
209
+
210
+ | Framework | Adapter | `ASK` becomes | Tested with |
211
+ |---|---|---|---|
212
+ | any Python tool | `@rg.guard(gate, context=...)` | `on_ask` hook or `ApprovalRequired` | — |
213
+ | LangGraph | `langgraph_gate_node`, `gated_tool_node` | `interrupt()` → `Command(resume=...)` | langgraph 1.2.12 |
214
+ | Google ADK | `adk_before_tool_callback`, `adk_plugin` | ADK tool confirmation | google-adk 2.11.0 |
215
+ | OpenAI Agents SDK | `guarded_function_tool`, `riskgate_tool_input_guardrail`, `riskgate_needs_approval` | SDK approval interruptions | openai-agents 0.23.1 |
216
+ | any MCP client | `riskgate serve-mcp ... -- <upstream server>` | `isError` result with the gate's feedback | mcp 2.3.0 |
217
+
218
+ Each adapter has offline contract tests (fake models, no network). See [docs/integrations.md](https://github.com/reallysaurabh/riskgate/blob/main/docs/integrations.md)
219
+ and [examples/integrations/](https://github.com/reallysaurabh/riskgate/tree/main/examples/integrations/).
220
+
221
+ ## Command line
222
+
223
+ ```bash
224
+ riskgate calibrate --gate mypkg.gates:make_gate --episodes mypkg.data:load --out gate.cal.json --key "$RISKGATE_KEY"
225
+ riskgate report gate.cal.json --key "$RISKGATE_KEY" # thresholds, plausible-set size, probing, fingerprint
226
+ riskgate validate gate.cal.json --gate mypkg.gates:make_gate # exit 3 if the artefact no longer matches the code
227
+ riskgate audit-summary decisions.jsonl # verdict counts, statuses, latency percentiles
228
+ riskgate serve-mcp --gate mypkg.gates:make_gate --calibration gate.cal.json -- python upstream_server.py
229
+ ```
230
+
231
+ ## Results on three simulated domains
232
+
233
+ All numbers are from **simulated** domains with scripted (LLM-like) agents, α = 5%. "riskgate" columns are means
234
+ over random re-splits of calibration and test data, which is what conformal risk control bounds. Full tables,
235
+ ablations and caveats: [docs/results.md](https://github.com/reallysaurabh/riskgate/blob/main/docs/results.md).
236
+
237
+ | Domain (consequence model) | agent's first choice unsafe | binary twin gate: unsafe | **riskgate: unsafe** | riskgate: asks a human | single-diagnosis CRC: asks |
238
+ |---|---|---|---|---|---|
239
+ | Chemical reactor (first-principles twin) | 36.2% | 16.2% | **4.6%** | 33.6% | 90.7% |
240
+ | Kubernetes incident (queueing twin) | 36.2% | 6.9% | **4.0%** | 22.7% | 19.3% |
241
+ | Refunds (SQLite dry-run) | 40.6% | 8.1% | **1.6%** | 25.7% | 100% |
242
+
243
+ - Calibrating around the single most likely diagnosis is valid but useless where misdiagnoses matter (it asks about
244
+ almost everything); in the Kubernetes domain it is competitive, and we say so.
245
+ - Probing (e.g. "read the backup thermocouple first") cuts the ask rate by 14–29% (relative, fixed split) while keeping the total risk ≤ α.
246
+ - **Honest caveat:** on one fixed split the reactor's unsafe rate was 9.2%. An expectation guarantee allows such
247
+ splits; a cliff in that domain's risk curve makes them more likely. `guarantee="high_probability"` (6.2% on that
248
+ split, no re-split above α in any domain) is the fix when you need the bound for your own artefact.
249
+
250
+ ![validity over re-splits](https://raw.githubusercontent.com/reallysaurabh/riskgate/main/examples/results/validity_resplits.png)
251
+
252
+ ## Results on real agents (public benchmarks)
253
+
254
+ [`benchmarks/`](https://github.com/reallysaurabh/riskgate/tree/main/benchmarks/) evaluates the same library offline on logs published with public benchmarks.
255
+ - No LLM is called; the gate is LLM-free by design.
256
+ - Tasks are the exchangeable units (`calibrate(groups=...)`).
257
+ - Every number is a mean over 200 random task re-splits.
258
+ - Protocol: [benchmarks/README.md](https://github.com/reallysaurabh/riskgate/blob/main/benchmarks/README.md). Details: [docs/results_real_agents.md](https://github.com/reallysaurabh/riskgate/blob/main/docs/results_real_agents.md).
259
+
260
+ | Benchmark | Real data | Headline |
261
+ |---|---|---|
262
+ | τ²-bench retail, 2026 leaderboard | 4,855 database writes by 8 frontier agents | wrong writes 5.0–9.6%; with RiskGate at α = 10%, unsafe 7.3–8.9% for every agent; asks on 6–28% of writes (53–70% at α = 5%) |
263
+ | τ²-bench airline, 2026 leaderboard | 1,370 writes by the same agents | wrong writes 8.9–26.5%; with RiskGate at α = 10%, unsafe 4.6–5.9%; asks on 35–80% (α = 5% is infeasible with 50 tasks) |
264
+ | ITBench SRE | 85 root-cause claims by a GPT-OSS-120B agent | claims right in 17.6%; evidence gate AUROC 0.90; too few scenarios for α ≤ 10% |
265
+ | RCAEval | real fault-injection telemetry | true root cause in the conformal plausible set 96.2% of the time at δ = 5% (mean size 4.2 of 55) |
266
+ | AgentDojo prompt injection | 20,833 state-changing calls by 28 model/defence pipelines (benign + `important_instructions` runs) | at α = 5%, re-split unsafe 0.2–3.1% across all 27 held-out pipelines (median 2.0%, vs median base 29.3%); median attack success 12.3% → 1.5% with 100% (median) of benign runs needing no human |
267
+ | Refund Arena (Sep 2026) | 200 synthetic tickets, 80 boundary-pair orders | SQLite dry-run reproduces all 445 gold labels under the true intent; policy check is already exact on held-out tickets |
268
+ | Tennessee Eastman (Rieth 2017) | 500 runs per fault (81,900 held-out windows) | top-1 80.0%; conformal fault set covers 95.0% at δ = 5% (mean size 2.1), widening to 4.7 classes on the undetectable IDV 3/9/15 |
269
+
270
+ What the real logs show:
271
+ - **The bound held for every agent** (12 τ²-bench agents, 28 AgentDojo pipelines).
272
+ - **Efficiency depends on the hypothesis provider.** Lexical readings barely separate frontier agents' remaining errors
273
+ (AUROC 0.49–0.65). Readings from other agents' runs reach 0.92–0.96, but that is an optimistic upper bound.
274
+ - **Confirmation is not verification.** 355 of 363 wrong retail writes came right after an explicit "yes".
275
+ - **Calibrated beats blunt.** Against prompt injection, a rule that blocks every call with an untrusted address stops
276
+ attacks about as well (median 1.6% vs 1.5%) but lets only 68% of benign runs through without a human (RiskGate: 100%).
277
+ - **Recalibrate when the agent changes.** A calibration fitted to 2025 agents gave 14.6% unsafe on the 2026 agents in
278
+ airline at α = 10%; swapping AgentDojo pipelines exceeded α in 35% of pairs. Set `doer_id` so a swap voids the
279
+ calibration (policy mode warns if it is missing).
280
+ - **Count tasks, not tool calls.** With grouped calibration the risk-control split needs at least ⌈1/α⌉ independent
281
+ tasks (20 at α = 5%, about 29 in total with the default 30% τ split), and the high-probability guarantee at α = 5%,
282
+ δ' = 0.1 needs about 45 loss-free tasks before it certifies anything.
283
+
284
+ ## Documentation
285
+
286
+ | Page | For |
287
+ |---|---|
288
+ | [Concepts](https://github.com/reallysaurabh/riskgate/blob/main/docs/concepts.md) | the picture, the verdicts, the components |
289
+ | [Quickstart](https://github.com/reallysaurabh/riskgate/blob/main/docs/quickstart.md) | the tank example, step by step |
290
+ | [End-to-end tutorial](https://github.com/reallysaurabh/riskgate/blob/main/docs/end_to_end.md) | an SRE agent's full lifecycle, with real output |
291
+ | [Bring your own domain](https://github.com/reallysaurabh/riskgate/blob/main/docs/byo_domain.md) | templates for your simulator, diagnoser and spec |
292
+ | [Use cases](https://github.com/reallysaurabh/riskgate/blob/main/docs/use_cases.md) | the sixteen stories of the RiskGate site, mapped to building blocks and scripts |
293
+ | [Calibration & guarantees](https://github.com/reallysaurabh/riskgate/blob/main/docs/calibration.md) | exactly what is promised, and how |
294
+ | [Operations](https://github.com/reallysaurabh/riskgate/blob/main/docs/operations.md) | artefacts, signing, monitoring, recalibration, audit, OpenTelemetry |
295
+ | [Integrations](https://github.com/reallysaurabh/riskgate/blob/main/docs/integrations.md) | LangGraph, ADK, OpenAI Agents SDK, MCP |
296
+ | [CLI](https://github.com/reallysaurabh/riskgate/blob/main/docs/cli.md) · [Configuration](https://github.com/reallysaurabh/riskgate/blob/main/docs/configuration.md) · [API reference](https://github.com/reallysaurabh/riskgate/blob/main/docs/api.md) | reference |
297
+ | [Results](https://github.com/reallysaurabh/riskgate/blob/main/docs/results.md) | all tables, ablations, honest caveats |
298
+ | [Results on real agents](https://github.com/reallysaurabh/riskgate/blob/main/docs/results_real_agents.md) | offline replays of public benchmark logs (τ²-bench, AgentDojo, ITBench, RCAEval, Refund Arena, TEP) |
299
+ | [FAQ](https://github.com/reallysaurabh/riskgate/blob/main/docs/faq.md) | common questions |
300
+ | [Specification](https://github.com/reallysaurabh/riskgate/blob/main/docs/SPEC.md) | design |
301
+
302
+ The accompanying paper is under submission; a link will be added here once it is public.
303
+
304
+ ## Project status
305
+
306
+ Release candidate `1.0.0rc3`. Implemented and tested (100+ tests including statistical validity tests,
307
+ fuzzed fail-closed tests and framework contract tests): the core gate, both guarantee modes, high-probability and
308
+ multi-risk calibration, weighted CRC, grouped calibration for dependent decisions, STL specifications, two-stage
309
+ probing, drift monitoring with tighten-only adaptation, delayed outcomes and recalibration, signed artefacts, audit and
310
+ OpenTelemetry sinks, configuration files, the CLI, four framework adapters, three example domains with released
311
+ calibration data, and offline evaluations on public real-agent logs ([`benchmarks/`](https://github.com/reallysaurabh/riskgate/tree/main/benchmarks/)).
312
+
313
+ Not done yet:
314
+ - online evaluations with live LLM agents and real users (the `riskgate.doers.LLMRanker` adapter is ready); the
315
+ real-agent results so far are offline replays of published logs;
316
+ - the paper is under submission (no public link yet).
317
+
318
+ ## Responsible use
319
+
320
+ riskgate is a research-grade **supervisory** layer. It does not replace certified safety systems (safety
321
+ instrumented systems, interlocks), access control or human oversight, and its guarantee is statistical, not a
322
+ proof. Treat `VOID` and `DEGRADED` seriously, and keep catastrophic or irreversible actions behind hard rules.
323
+
324
+ ## Citation
325
+
326
+ ```bibtex
327
+ @misc{gupta2026riskgate,
328
+ title = {RiskGate: Certify, Reject or Ask. Hypothesis-Robust, Distribution-Free Risk Control
329
+ for the Actions of LLM Agents},
330
+ author = {Gupta, Saurabh},
331
+ year = {2026},
332
+ note = {Under submission; software: riskgate 1.0.0rc3}
333
+ }
334
+ ```
335
+
336
+ ## License
337
+
338
+ [Apache-2.0](https://github.com/reallysaurabh/riskgate/blob/main/LICENSE).