agenticrail 0.1.0__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.
@@ -0,0 +1,29 @@
1
+ .env
2
+ .env.*
3
+ *.env
4
+
5
+ node_modules/
6
+ .wrangler/
7
+ *.log
8
+ __pycache__/
9
+ *.pyc
10
+ *.pyo
11
+ sdks/python/dist/
12
+ sdks/js/core/dist/
13
+ .DS_Store
14
+ Thumbs.db
15
+
16
+ .claude/
17
+
18
+ # Personal/internal — local only, never push
19
+ CLAUDE.md
20
+ CODEBASE_OVERVIEW.md
21
+ start-claudeV2.ps1
22
+ *.ps1
23
+
24
+ # Sub-repos — tracked separately
25
+ agenticrail-v1/
26
+ agenticrail-wrapper/
27
+ clients/
28
+ website/
29
+ archive/
@@ -0,0 +1,304 @@
1
+ Metadata-Version: 2.4
2
+ Name: agenticrail
3
+ Version: 0.1.0
4
+ Summary: AgenticRail SDK — deterministic sequence enforcement for AI agents
5
+ Project-URL: Homepage, https://agenticrail.nz
6
+ Project-URL: Documentation, https://agenticrail.nz/docs
7
+ Project-URL: Repository, https://github.com/MSMD-RUA/agenticrail-sdk
8
+ Project-URL: Bug Tracker, https://github.com/MSMD-RUA/agenticrail-sdk/issues
9
+ License: MIT
10
+ Keywords: ai-agents,compliance,crewai,enforcement,langgraph,sequence
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Topic :: Software Development :: Libraries
20
+ Requires-Python: >=3.9
21
+ Requires-Dist: requests>=2.28
22
+ Provides-Extra: all
23
+ Requires-Dist: crewai>=0.60; extra == 'all'
24
+ Requires-Dist: langchain-core>=0.1; extra == 'all'
25
+ Requires-Dist: langgraph>=0.1; extra == 'all'
26
+ Provides-Extra: crewai
27
+ Requires-Dist: crewai>=0.60; extra == 'crewai'
28
+ Provides-Extra: dev
29
+ Requires-Dist: pytest-mock; extra == 'dev'
30
+ Requires-Dist: pytest>=7; extra == 'dev'
31
+ Requires-Dist: responses; extra == 'dev'
32
+ Provides-Extra: langgraph
33
+ Requires-Dist: langchain-core>=0.1; extra == 'langgraph'
34
+ Requires-Dist: langgraph>=0.1; extra == 'langgraph'
35
+ Description-Content-Type: text/markdown
36
+
37
+ # agenticrail
38
+
39
+ AgenticRail Python SDK — deterministic sequence enforcement for AI agents.
40
+
41
+ Gate every step of your agent workflow before it executes. Cryptographic receipts. Zero enforcement failures.
42
+
43
+ ```
44
+ pip install agenticrail
45
+ ```
46
+
47
+ ---
48
+
49
+ ## What it does
50
+
51
+ AgenticRail sits beneath your agent and enforces that steps run in the right order, with no skips, no replays, and no re-entry after a sequence is sealed. Every decision — ALLOW, DENY, or HALT — produces a cryptographically signed receipt stored at the edge.
52
+
53
+ Three verdicts:
54
+ - **ALLOW** — step is clear, your agent code executes
55
+ - **DENY** — enforcement violation (wrong order, replay, sealed), execution blocked
56
+ - **HALT** — hard stop (injection attempt, poison payload detected), execution blocked
57
+
58
+ ---
59
+
60
+ ## Install
61
+
62
+ ```bash
63
+ # Core client only
64
+ pip install agenticrail
65
+
66
+ # With LangGraph support
67
+ pip install "agenticrail[langgraph]"
68
+
69
+ # With CrewAI support
70
+ pip install "agenticrail[crewai]"
71
+
72
+ # Everything
73
+ pip install "agenticrail[all]"
74
+ ```
75
+
76
+ ---
77
+
78
+ ## Quick start — any framework
79
+
80
+ ```python
81
+ from agenticrail import RailClient
82
+
83
+ client = RailClient(api_key="DEMO-AGENTICRAIL-PUBLIC-2026")
84
+
85
+ # RailSequence sends step_order on every call — the gate reads it from each payload
86
+ seq = client.sequence(
87
+ sequence_id="my-agent-run-001",
88
+ step_order=["verify_identity", "assess_risk", "execute_transfer", "audit_ledger"],
89
+ )
90
+
91
+ seq.next("verify_identity") # → ALLOW
92
+ seq.next("assess_risk") # → ALLOW
93
+ seq.next("execute_transfer") # → ALLOW
94
+ seq.next("audit_ledger") # → ALLOW (seals sequence)
95
+
96
+ # Any out-of-order, replay, or post-seal call raises RailDenied
97
+ seq.next("verify_identity") # → raises RailDenied: SEALED_SEQUENCE
98
+ ```
99
+
100
+ Get a production API key at [agenticrail.nz](https://agenticrail.nz).
101
+
102
+ ---
103
+
104
+ ## LangGraph integration
105
+
106
+ Wrap each node at `add_node` time. Uses `thread_id` from LangGraph config as the sequence_id — each graph invocation is isolated.
107
+
108
+ ```python
109
+ from langgraph.graph import StateGraph, END
110
+ from agenticrail import RailClient
111
+ from agenticrail.integrations.langgraph import LangGraphRail
112
+
113
+ client = RailClient(api_key="YOUR_KEY")
114
+ rail = LangGraphRail(
115
+ client,
116
+ step_order=["research", "analyze", "write_report", "review"],
117
+ )
118
+
119
+ builder = StateGraph(AgentState)
120
+
121
+ # Wrap each node — gate fires before node execution
122
+ builder.add_node("research", rail.wrap("research", research_fn))
123
+ builder.add_node("analyze", rail.wrap("analyze", analyze_fn))
124
+ builder.add_node("write_report", rail.wrap("write_report", write_report_fn))
125
+ builder.add_node("review", rail.wrap("review", review_fn))
126
+
127
+ builder.set_entry_point("research")
128
+ builder.add_edge("research", "analyze")
129
+ builder.add_edge("analyze", "write_report")
130
+ builder.add_edge("write_report", "review")
131
+ builder.add_edge("review", END)
132
+
133
+ graph = builder.compile()
134
+
135
+ # thread_id → sequence_id: each invocation is independently tracked and verifiable
136
+ result = graph.invoke(
137
+ {"query": "EU AI Act compliance checklist"},
138
+ config={"configurable": {"thread_id": "run-2026-001"}},
139
+ )
140
+ ```
141
+
142
+ **What happens on DENY or HALT:**
143
+ `rail.wrap()` raises `RailDenied` inside the node. LangGraph catches unhandled node exceptions and halts graph execution. No subsequent nodes run.
144
+
145
+ **Concurrent runs:**
146
+ Each `thread_id` is a separate sequence. Concurrent graph invocations with different thread IDs do not interfere — the gate tracks them independently via Durable Objects.
147
+
148
+ ---
149
+
150
+ ## CrewAI integration
151
+
152
+ Use `guard.kickoff()` instead of `crew.kickoff()`. Step[0] is gated before the crew starts; subsequent steps are gated via a task callback injected between tasks.
153
+
154
+ ```python
155
+ from crewai import Crew
156
+ from agenticrail import RailClient
157
+ from agenticrail.integrations.crewai import CrewRailGuard
158
+
159
+ client = RailClient(api_key="YOUR_KEY")
160
+ guard = CrewRailGuard(
161
+ client,
162
+ step_order=["research_task", "analysis_task", "write_task"],
163
+ )
164
+
165
+ crew = Crew(
166
+ agents=[researcher, analyst, writer],
167
+ tasks=[research_task, analysis_task, write_task],
168
+ )
169
+
170
+ # Drop-in replacement for crew.kickoff()
171
+ # Each call generates a fresh sequence_id — each run is independently tracked
172
+ result = guard.kickoff(crew, inputs={"topic": "AI governance"})
173
+ ```
174
+
175
+ **Note on blocking:** CrewAI's `task_callback` fires synchronously between tasks, so the gate can block task N before task N starts. However, if CrewAI swallows exceptions in callbacks, a denied task may still execute. In that case, `guard.kickoff()` raises `RailDenied` after the crew finishes, preserving the denial in the audit trail.
176
+
177
+ For hard blocking (guaranteed pre-execution), use `guard.gate()` in a custom orchestration loop:
178
+
179
+ ```python
180
+ guard.reset()
181
+ for step, task_fn in zip(STEP_ORDER, task_functions):
182
+ guard.gate(step) # raises RailDenied immediately on DENY
183
+ task_fn()
184
+ ```
185
+
186
+ ---
187
+
188
+ ## API reference
189
+
190
+ ### `RailClient`
191
+
192
+ ```python
193
+ client = RailClient(
194
+ api_key="...", # Required. Bearer token for the wrapper API.
195
+ model_id="agent", # Optional. Identifies your agent in receipts.
196
+ base_url=None, # Optional. Defaults to api.agenticrail.nz/v1/evaluate.
197
+ timeout=10, # Optional. Request timeout in seconds.
198
+ )
199
+ ```
200
+
201
+ #### `client.evaluate(sequence_id, step, *, ...)`
202
+
203
+ ```python
204
+ decision = client.evaluate(
205
+ sequence_id="my-run-001",
206
+ step="verify_identity",
207
+ action_type="CHECK_STATE", # Optional. Default: CHECK_STATE.
208
+ action="verify user identity", # Optional. Human-readable label.
209
+ inputs={"user_id": "u123"}, # Optional. Metadata attached to receipt.
210
+ step_order=[...], # Required on every call — gate reads it from each payload.
211
+ raise_on_deny=True, # Optional. Default True.
212
+ )
213
+ # decision.decision → "ALLOW" | "DENY" | "HALT"
214
+ # decision.allowed → True if ALLOW
215
+ # decision.pack_id → SHA-256 receipt hash
216
+ # decision.receipt → full signed receipt dict
217
+ # decision.reasons → list of reason codes on DENY/HALT
218
+ ```
219
+
220
+ #### `client.sequence(sequence_id, step_order)`
221
+
222
+ Returns a `RailSequence` that tracks `step_order` state — call `.next(step)` for each step without managing `step_order` yourself.
223
+
224
+ ### `RailDenied`
225
+
226
+ ```python
227
+ try:
228
+ seq.next("execute_transfer")
229
+ except RailDenied as e:
230
+ print(e.decision) # "DENY" or "HALT"
231
+ print(e.reasons) # ["SEQUENCE_VIOLATION"]
232
+ print(e.pack_id) # receipt hash for audit
233
+ print(e.step) # "execute_transfer"
234
+ ```
235
+
236
+ ### `LangGraphRail`
237
+
238
+ ```python
239
+ rail = LangGraphRail(
240
+ client,
241
+ step_order=["step_a", "step_b", "step_c"],
242
+ fallback_sequence_id=None, # Used when thread_id not in config
243
+ )
244
+ wrapped_fn = rail.wrap("step_a", original_fn, action_type="CHECK_STATE")
245
+ ```
246
+
247
+ ### `CrewRailGuard`
248
+
249
+ ```python
250
+ guard = CrewRailGuard(
251
+ client,
252
+ step_order=["task_1", "task_2", "task_3"],
253
+ sequence_id=None, # Optional. Auto-generated per kickoff() call if None.
254
+ action_type="CHECK_STATE",
255
+ )
256
+ result = guard.kickoff(crew, inputs={...})
257
+ guard.gate("task_1") # Explicit gate for custom loops
258
+ guard.reset() # Reset state for a new run
259
+ ```
260
+
261
+ ---
262
+
263
+ ## Compliance reports
264
+
265
+ Every `pack_id` in a `RailDecision` is a verifiable receipt. Paste your sequence ID into the report generator or call it programmatically:
266
+
267
+ ```bash
268
+ curl -X POST https://api.agenticrail.nz/v1/report \
269
+ -H "Authorization: Bearer YOUR_KEY" \
270
+ -H "Content-Type: application/json" \
271
+ -d '{"sequence_id": "my-run-001", "format": "json"}'
272
+ ```
273
+
274
+ Returns: chain proof, HMAC verification, enforcement log, AI-written compliance narrative (EU AI Act Article 11).
275
+
276
+ Demo sequences (using `DEMO-AGENTICRAIL-PUBLIC-2026`) are verifiable at [report.agenticrail.nz](https://report.agenticrail.nz) — no auth needed.
277
+
278
+ ---
279
+
280
+ ## Action types
281
+
282
+ | Type | Use when |
283
+ |------|----------|
284
+ | `CHECK_STATE` | Reading or observing state (default) |
285
+ | `VALIDATE_INPUT` | Verifying inputs before acting |
286
+ | `RECORD_RESULT` | Writing or committing an outcome |
287
+ | `CLARIFY_NEXT_STEP` | Asking for clarification |
288
+ | `SELECT_NEXT_STEP` | Choosing a path |
289
+ | `WAIT_FOR_SIGNAL` | Pausing for an external trigger |
290
+ | `PAUSE_CYCLE` | Deliberate suspension |
291
+ | `REDUCE_STIMULUS` | Backing off |
292
+
293
+ ---
294
+
295
+ ## Links
296
+
297
+ - **API docs:** [agenticrail.nz/docs](https://agenticrail.nz/docs)
298
+ - **Interactive demo:** [agenticrail.nz/demo](https://agenticrail.nz/demo)
299
+ - **Compliance matrix (60+ frameworks):** [agenticrail.nz/compliance](https://agenticrail.nz/compliance)
300
+ - **Verify a sequence:** [report.agenticrail.nz](https://report.agenticrail.nz)
301
+
302
+ ---
303
+
304
+ *TUARA KURI LIMITED — trading as AgenticRail. Hokianga, New Zealand.*
@@ -0,0 +1,268 @@
1
+ # agenticrail
2
+
3
+ AgenticRail Python SDK — deterministic sequence enforcement for AI agents.
4
+
5
+ Gate every step of your agent workflow before it executes. Cryptographic receipts. Zero enforcement failures.
6
+
7
+ ```
8
+ pip install agenticrail
9
+ ```
10
+
11
+ ---
12
+
13
+ ## What it does
14
+
15
+ AgenticRail sits beneath your agent and enforces that steps run in the right order, with no skips, no replays, and no re-entry after a sequence is sealed. Every decision — ALLOW, DENY, or HALT — produces a cryptographically signed receipt stored at the edge.
16
+
17
+ Three verdicts:
18
+ - **ALLOW** — step is clear, your agent code executes
19
+ - **DENY** — enforcement violation (wrong order, replay, sealed), execution blocked
20
+ - **HALT** — hard stop (injection attempt, poison payload detected), execution blocked
21
+
22
+ ---
23
+
24
+ ## Install
25
+
26
+ ```bash
27
+ # Core client only
28
+ pip install agenticrail
29
+
30
+ # With LangGraph support
31
+ pip install "agenticrail[langgraph]"
32
+
33
+ # With CrewAI support
34
+ pip install "agenticrail[crewai]"
35
+
36
+ # Everything
37
+ pip install "agenticrail[all]"
38
+ ```
39
+
40
+ ---
41
+
42
+ ## Quick start — any framework
43
+
44
+ ```python
45
+ from agenticrail import RailClient
46
+
47
+ client = RailClient(api_key="DEMO-AGENTICRAIL-PUBLIC-2026")
48
+
49
+ # RailSequence sends step_order on every call — the gate reads it from each payload
50
+ seq = client.sequence(
51
+ sequence_id="my-agent-run-001",
52
+ step_order=["verify_identity", "assess_risk", "execute_transfer", "audit_ledger"],
53
+ )
54
+
55
+ seq.next("verify_identity") # → ALLOW
56
+ seq.next("assess_risk") # → ALLOW
57
+ seq.next("execute_transfer") # → ALLOW
58
+ seq.next("audit_ledger") # → ALLOW (seals sequence)
59
+
60
+ # Any out-of-order, replay, or post-seal call raises RailDenied
61
+ seq.next("verify_identity") # → raises RailDenied: SEALED_SEQUENCE
62
+ ```
63
+
64
+ Get a production API key at [agenticrail.nz](https://agenticrail.nz).
65
+
66
+ ---
67
+
68
+ ## LangGraph integration
69
+
70
+ Wrap each node at `add_node` time. Uses `thread_id` from LangGraph config as the sequence_id — each graph invocation is isolated.
71
+
72
+ ```python
73
+ from langgraph.graph import StateGraph, END
74
+ from agenticrail import RailClient
75
+ from agenticrail.integrations.langgraph import LangGraphRail
76
+
77
+ client = RailClient(api_key="YOUR_KEY")
78
+ rail = LangGraphRail(
79
+ client,
80
+ step_order=["research", "analyze", "write_report", "review"],
81
+ )
82
+
83
+ builder = StateGraph(AgentState)
84
+
85
+ # Wrap each node — gate fires before node execution
86
+ builder.add_node("research", rail.wrap("research", research_fn))
87
+ builder.add_node("analyze", rail.wrap("analyze", analyze_fn))
88
+ builder.add_node("write_report", rail.wrap("write_report", write_report_fn))
89
+ builder.add_node("review", rail.wrap("review", review_fn))
90
+
91
+ builder.set_entry_point("research")
92
+ builder.add_edge("research", "analyze")
93
+ builder.add_edge("analyze", "write_report")
94
+ builder.add_edge("write_report", "review")
95
+ builder.add_edge("review", END)
96
+
97
+ graph = builder.compile()
98
+
99
+ # thread_id → sequence_id: each invocation is independently tracked and verifiable
100
+ result = graph.invoke(
101
+ {"query": "EU AI Act compliance checklist"},
102
+ config={"configurable": {"thread_id": "run-2026-001"}},
103
+ )
104
+ ```
105
+
106
+ **What happens on DENY or HALT:**
107
+ `rail.wrap()` raises `RailDenied` inside the node. LangGraph catches unhandled node exceptions and halts graph execution. No subsequent nodes run.
108
+
109
+ **Concurrent runs:**
110
+ Each `thread_id` is a separate sequence. Concurrent graph invocations with different thread IDs do not interfere — the gate tracks them independently via Durable Objects.
111
+
112
+ ---
113
+
114
+ ## CrewAI integration
115
+
116
+ Use `guard.kickoff()` instead of `crew.kickoff()`. Step[0] is gated before the crew starts; subsequent steps are gated via a task callback injected between tasks.
117
+
118
+ ```python
119
+ from crewai import Crew
120
+ from agenticrail import RailClient
121
+ from agenticrail.integrations.crewai import CrewRailGuard
122
+
123
+ client = RailClient(api_key="YOUR_KEY")
124
+ guard = CrewRailGuard(
125
+ client,
126
+ step_order=["research_task", "analysis_task", "write_task"],
127
+ )
128
+
129
+ crew = Crew(
130
+ agents=[researcher, analyst, writer],
131
+ tasks=[research_task, analysis_task, write_task],
132
+ )
133
+
134
+ # Drop-in replacement for crew.kickoff()
135
+ # Each call generates a fresh sequence_id — each run is independently tracked
136
+ result = guard.kickoff(crew, inputs={"topic": "AI governance"})
137
+ ```
138
+
139
+ **Note on blocking:** CrewAI's `task_callback` fires synchronously between tasks, so the gate can block task N before task N starts. However, if CrewAI swallows exceptions in callbacks, a denied task may still execute. In that case, `guard.kickoff()` raises `RailDenied` after the crew finishes, preserving the denial in the audit trail.
140
+
141
+ For hard blocking (guaranteed pre-execution), use `guard.gate()` in a custom orchestration loop:
142
+
143
+ ```python
144
+ guard.reset()
145
+ for step, task_fn in zip(STEP_ORDER, task_functions):
146
+ guard.gate(step) # raises RailDenied immediately on DENY
147
+ task_fn()
148
+ ```
149
+
150
+ ---
151
+
152
+ ## API reference
153
+
154
+ ### `RailClient`
155
+
156
+ ```python
157
+ client = RailClient(
158
+ api_key="...", # Required. Bearer token for the wrapper API.
159
+ model_id="agent", # Optional. Identifies your agent in receipts.
160
+ base_url=None, # Optional. Defaults to api.agenticrail.nz/v1/evaluate.
161
+ timeout=10, # Optional. Request timeout in seconds.
162
+ )
163
+ ```
164
+
165
+ #### `client.evaluate(sequence_id, step, *, ...)`
166
+
167
+ ```python
168
+ decision = client.evaluate(
169
+ sequence_id="my-run-001",
170
+ step="verify_identity",
171
+ action_type="CHECK_STATE", # Optional. Default: CHECK_STATE.
172
+ action="verify user identity", # Optional. Human-readable label.
173
+ inputs={"user_id": "u123"}, # Optional. Metadata attached to receipt.
174
+ step_order=[...], # Required on every call — gate reads it from each payload.
175
+ raise_on_deny=True, # Optional. Default True.
176
+ )
177
+ # decision.decision → "ALLOW" | "DENY" | "HALT"
178
+ # decision.allowed → True if ALLOW
179
+ # decision.pack_id → SHA-256 receipt hash
180
+ # decision.receipt → full signed receipt dict
181
+ # decision.reasons → list of reason codes on DENY/HALT
182
+ ```
183
+
184
+ #### `client.sequence(sequence_id, step_order)`
185
+
186
+ Returns a `RailSequence` that tracks `step_order` state — call `.next(step)` for each step without managing `step_order` yourself.
187
+
188
+ ### `RailDenied`
189
+
190
+ ```python
191
+ try:
192
+ seq.next("execute_transfer")
193
+ except RailDenied as e:
194
+ print(e.decision) # "DENY" or "HALT"
195
+ print(e.reasons) # ["SEQUENCE_VIOLATION"]
196
+ print(e.pack_id) # receipt hash for audit
197
+ print(e.step) # "execute_transfer"
198
+ ```
199
+
200
+ ### `LangGraphRail`
201
+
202
+ ```python
203
+ rail = LangGraphRail(
204
+ client,
205
+ step_order=["step_a", "step_b", "step_c"],
206
+ fallback_sequence_id=None, # Used when thread_id not in config
207
+ )
208
+ wrapped_fn = rail.wrap("step_a", original_fn, action_type="CHECK_STATE")
209
+ ```
210
+
211
+ ### `CrewRailGuard`
212
+
213
+ ```python
214
+ guard = CrewRailGuard(
215
+ client,
216
+ step_order=["task_1", "task_2", "task_3"],
217
+ sequence_id=None, # Optional. Auto-generated per kickoff() call if None.
218
+ action_type="CHECK_STATE",
219
+ )
220
+ result = guard.kickoff(crew, inputs={...})
221
+ guard.gate("task_1") # Explicit gate for custom loops
222
+ guard.reset() # Reset state for a new run
223
+ ```
224
+
225
+ ---
226
+
227
+ ## Compliance reports
228
+
229
+ Every `pack_id` in a `RailDecision` is a verifiable receipt. Paste your sequence ID into the report generator or call it programmatically:
230
+
231
+ ```bash
232
+ curl -X POST https://api.agenticrail.nz/v1/report \
233
+ -H "Authorization: Bearer YOUR_KEY" \
234
+ -H "Content-Type: application/json" \
235
+ -d '{"sequence_id": "my-run-001", "format": "json"}'
236
+ ```
237
+
238
+ Returns: chain proof, HMAC verification, enforcement log, AI-written compliance narrative (EU AI Act Article 11).
239
+
240
+ Demo sequences (using `DEMO-AGENTICRAIL-PUBLIC-2026`) are verifiable at [report.agenticrail.nz](https://report.agenticrail.nz) — no auth needed.
241
+
242
+ ---
243
+
244
+ ## Action types
245
+
246
+ | Type | Use when |
247
+ |------|----------|
248
+ | `CHECK_STATE` | Reading or observing state (default) |
249
+ | `VALIDATE_INPUT` | Verifying inputs before acting |
250
+ | `RECORD_RESULT` | Writing or committing an outcome |
251
+ | `CLARIFY_NEXT_STEP` | Asking for clarification |
252
+ | `SELECT_NEXT_STEP` | Choosing a path |
253
+ | `WAIT_FOR_SIGNAL` | Pausing for an external trigger |
254
+ | `PAUSE_CYCLE` | Deliberate suspension |
255
+ | `REDUCE_STIMULUS` | Backing off |
256
+
257
+ ---
258
+
259
+ ## Links
260
+
261
+ - **API docs:** [agenticrail.nz/docs](https://agenticrail.nz/docs)
262
+ - **Interactive demo:** [agenticrail.nz/demo](https://agenticrail.nz/demo)
263
+ - **Compliance matrix (60+ frameworks):** [agenticrail.nz/compliance](https://agenticrail.nz/compliance)
264
+ - **Verify a sequence:** [report.agenticrail.nz](https://report.agenticrail.nz)
265
+
266
+ ---
267
+
268
+ *TUARA KURI LIMITED — trading as AgenticRail. Hokianga, New Zealand.*
@@ -0,0 +1,6 @@
1
+ """AgenticRail SDK — deterministic sequence enforcement for AI agents."""
2
+
3
+ from agenticrail.client import RailClient, RailDecision, RailDenied, RailSequence
4
+
5
+ __all__ = ["RailClient", "RailDecision", "RailDenied", "RailSequence"]
6
+ __version__ = "0.1.0"