Reliability primitives for LangGraph — certified stagnation and integrity gates, backed by the Operon categorical framework.
Project description
operon-langgraph-gates
In-graph reliability gates for LangGraph — drop-in, cert-emitting.
LangGraph issue #6731 — "agent infinite-loops until recursion limit, burns tokens invisibly" — was closed as NOT_PLANNED. LangChain's answer: "use tool-call limits in middleware."
This package ships that missing native gate, plus a second one for checkpointer-write integrity. Two primitives. No framework adoption. ~10-line diff on an existing StateGraph.
Both gates run inside the graph: they route conditional edges and can short-circuit the next step. This is a deliberate contrast to post-hoc observability tools — an observer tells you an agent looped after the fact; a gate stops the loop mid-run and emits a replayable certificate of what fired it.
At a glance:
StagnationGate— Bayesian stagnation detection (Paper 4 §4.3, 0.960 on convergence / false-stagnation scenarios) with per-thread state, async + class-callable aware. See it live.IntegrityGate— user-defined invariants checked on every wrapped node's output; violations emit alanggraph_state_integritycertificate with replayable evidence. Detection-and-certification only; does not repair state.
Install
pip install operon-langgraph-gates
Requires operon-ai>=0.34.4 and langgraph>=1.0.
Quickstart
Break infinite loops (StagnationGate)
from langgraph.graph import StateGraph
from operon_langgraph_gates import StagnationGate
graph = StateGraph(State)
graph.add_node("think", StagnationGate.wrap(think_fn, threshold=0.1, history=10))
# Or attach to a conditional edge (route loop-detected runs elsewhere)
graph.add_conditional_edges(
"think",
StagnationGate.edge(forward="answer", break_to="escalate", threshold=0.1),
)
# Certificates collected from the run
certs = StagnationGate.collect(graph)
Backed by Paper 4 §4.3: convergence/false-stagnation accuracy 0.960 with real sentence embeddings (all-MiniLM-L6-v2, N = 300 trials). See docs/paper-citations.md for the full citation record, including the loop-detection caveat and a pointer to the archived benchmark data.
Catch state drift (IntegrityGate)
from langgraph.graph import StateGraph
from operon_langgraph_gates import IntegrityGate
gate = IntegrityGate(invariants=[has_required_user, budget_not_exceeded])
graph = StateGraph(State)
graph.add_node("tool_call", gate.wrap(tool_call_fn))
# Route runs that violated an invariant to a recovery node
graph.add_conditional_edges(
"tool_call",
gate.edge(forward="process", break_to="recover"),
)
# Certificates (one per thread, on first violation) are on the gate
certs = gate.certificates
Backed by Paper 4 §4, Table 3: in the paper's setup, the FULL variant (with DNARepair) achieves 100% detection and 100% repair of injected state corruption, vs 0%/0% for RAW and GUARDED. This package is detection-and-certification only — it does not repair state. It reformulates the idea as a LangGraph-native invariant gate. Paper 5 §3 establishes the preservation-under-compilation framework that the gate's certificate follows. See docs/paper-citations.md for verbatim quotes and the honest caveat.
Certificate theorem name and verification
StagnationGate emits certificates with theorem name behavioral_stability_windowed (not the core's shared behavioral_stability). The two differ in how they verify:
behavioral_stability(shared core):mean(severities) < threshold. Loses the per-window structure rolling-integral detection operates on.behavioral_stability_windowed(shared core, since operon-ai 0.36.0):max(per_window_severity_means) <= stability_threshold. Mirrors detection exactly.
Both verifiers are registered in operon_ai.core.certificate._THEOREM_FN_PATHS, so deserialized certificates resolve through _resolve_verify_fn without this package needing to be imported. Any consumer with operon-ai>=0.36.0 can round-trip a behavioral_stability_windowed certificate correctly.
Breaking change from pre-alpha prototypes
Earlier builds emitted certificates with theorem name behavioral_stability, bound to a locally-attached _verify_fn. That shape was semantically wrong — the shared verifier is flat-mean-based, so any cert round-tripped through serialization would silently revert to the wrong replay logic. Consumers that key on certificate.theorem == "behavioral_stability" must update to "behavioral_stability_windowed". No migration path; alpha.
Try it — HuggingFace Space
Operon StagnationGate Demo — interactive page: pick a preset (identical, diverse, noisy, slow drift), tune the gate parameters, watch is_stagnant flip and the certificate appear. Deterministic text trajectories — no LLM calls.
Examples
examples/01_stagnation_breaks_loop.ipynb— reproduces issue #6731 pathology, then fixes it with a ten-line diff.examples/02_integrity_catches_drift.ipynb— a three-node graph silently corrupts state;IntegrityGatecatches it with replayable evidence.
Status
Alpha. API may change before 0.1.0 stable. Feedback welcome via Issues.
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file operon_langgraph_gates-0.1.0a2.tar.gz.
File metadata
- Download URL: operon_langgraph_gates-0.1.0a2.tar.gz
- Upload date:
- Size: 44.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
81fd31df66eadfcdb620115ce52efc390552467fc4546070c89e05004188b152
|
|
| MD5 |
9af519983bd03ae454eac7f47291d93e
|
|
| BLAKE2b-256 |
97418c877373bc1ef74c8451cbf4b8e3fc315d1b1ea3093b953dd001a34eff0b
|
Provenance
The following attestation bundles were made for operon_langgraph_gates-0.1.0a2.tar.gz:
Publisher:
publish.yml on coredipper/operon-langgraph-gates
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
operon_langgraph_gates-0.1.0a2.tar.gz -
Subject digest:
81fd31df66eadfcdb620115ce52efc390552467fc4546070c89e05004188b152 - Sigstore transparency entry: 1340619124
- Sigstore integration time:
-
Permalink:
coredipper/operon-langgraph-gates@5a9034bde1c1bbfcf08ab463e9149e1135407147 -
Branch / Tag:
refs/tags/v0.1.0a2 - Owner: https://github.com/coredipper
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@5a9034bde1c1bbfcf08ab463e9149e1135407147 -
Trigger Event:
release
-
Statement type:
File details
Details for the file operon_langgraph_gates-0.1.0a2-py3-none-any.whl.
File metadata
- Download URL: operon_langgraph_gates-0.1.0a2-py3-none-any.whl
- Upload date:
- Size: 17.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d12324d0dd5dc006795b6b9debcd4be72aaf417c74e9b9a2351155c05e7897b9
|
|
| MD5 |
2648245789512c56627d3f74b19c8f08
|
|
| BLAKE2b-256 |
316eeda4e31d1aac13bf7128ae145a3dae2496bba81d0f7cc035ed240a4120d2
|
Provenance
The following attestation bundles were made for operon_langgraph_gates-0.1.0a2-py3-none-any.whl:
Publisher:
publish.yml on coredipper/operon-langgraph-gates
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
operon_langgraph_gates-0.1.0a2-py3-none-any.whl -
Subject digest:
d12324d0dd5dc006795b6b9debcd4be72aaf417c74e9b9a2351155c05e7897b9 - Sigstore transparency entry: 1340619127
- Sigstore integration time:
-
Permalink:
coredipper/operon-langgraph-gates@5a9034bde1c1bbfcf08ab463e9149e1135407147 -
Branch / Tag:
refs/tags/v0.1.0a2 - Owner: https://github.com/coredipper
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@5a9034bde1c1bbfcf08ab463e9149e1135407147 -
Trigger Event:
release
-
Statement type: