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.
- riskgate-1.0.0rc3/LICENSE +202 -0
- riskgate-1.0.0rc3/PKG-INFO +338 -0
- riskgate-1.0.0rc3/README.md +284 -0
- riskgate-1.0.0rc3/pyproject.toml +80 -0
- riskgate-1.0.0rc3/riskgate/__init__.py +29 -0
- riskgate-1.0.0rc3/riskgate/adapters/__init__.py +48 -0
- riskgate-1.0.0rc3/riskgate/adapters/frameworks.py +415 -0
- riskgate-1.0.0rc3/riskgate/adapters/mcp_proxy.py +239 -0
- riskgate-1.0.0rc3/riskgate/adapters/openai_agents.py +175 -0
- riskgate-1.0.0rc3/riskgate/adapters/tool.py +97 -0
- riskgate-1.0.0rc3/riskgate/audit.py +77 -0
- riskgate-1.0.0rc3/riskgate/cli.py +172 -0
- riskgate-1.0.0rc3/riskgate/config.py +181 -0
- riskgate-1.0.0rc3/riskgate/conformal.py +98 -0
- riskgate-1.0.0rc3/riskgate/doers.py +69 -0
- riskgate-1.0.0rc3/riskgate/gate.py +889 -0
- riskgate-1.0.0rc3/riskgate/monitor.py +147 -0
- riskgate-1.0.0rc3/riskgate/multirisk.py +266 -0
- riskgate-1.0.0rc3/riskgate/provenance.py +206 -0
- riskgate-1.0.0rc3/riskgate/py.typed +0 -0
- riskgate-1.0.0rc3/riskgate/replay.py +182 -0
- riskgate-1.0.0rc3/riskgate/rules.py +86 -0
- riskgate-1.0.0rc3/riskgate/spec.py +163 -0
- riskgate-1.0.0rc3/riskgate/stl.py +492 -0
- riskgate-1.0.0rc3/riskgate/telemetry.py +67 -0
- riskgate-1.0.0rc3/riskgate/types.py +205 -0
- riskgate-1.0.0rc3/riskgate/weighted.py +175 -0
- riskgate-1.0.0rc3/riskgate/worlds.py +237 -0
- riskgate-1.0.0rc3/riskgate.egg-info/PKG-INFO +338 -0
- riskgate-1.0.0rc3/riskgate.egg-info/SOURCES.txt +42 -0
- riskgate-1.0.0rc3/riskgate.egg-info/dependency_links.txt +1 -0
- riskgate-1.0.0rc3/riskgate.egg-info/entry_points.txt +2 -0
- riskgate-1.0.0rc3/riskgate.egg-info/requires.txt +35 -0
- riskgate-1.0.0rc3/riskgate.egg-info/top_level.txt +1 -0
- riskgate-1.0.0rc3/setup.cfg +4 -0
- riskgate-1.0.0rc3/tests/test_core.py +197 -0
- riskgate-1.0.0rc3/tests/test_examples.py +45 -0
- riskgate-1.0.0rc3/tests/test_features.py +578 -0
- riskgate-1.0.0rc3/tests/test_groups.py +119 -0
- riskgate-1.0.0rc3/tests/test_multirisk.py +187 -0
- riskgate-1.0.0rc3/tests/test_stl.py +342 -0
- riskgate-1.0.0rc3/tests/test_use_case_kits.py +303 -0
- riskgate-1.0.0rc3/tests/test_warnings.py +62 -0
- 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
|
+

|
|
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).
|