ramen-foundry 0.1.1__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,9 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ .venv/
4
+ dist/
5
+ build/
6
+ *.egg-info/
7
+ .pytest_cache/
8
+ .mypy_cache/
9
+ .DS_Store
@@ -0,0 +1,310 @@
1
+ Metadata-Version: 2.5
2
+ Name: ramen-foundry
3
+ Version: 0.1.1
4
+ Summary: LangGraph governance nodes and human-review workflow templates powered by ramen-ai.
5
+ Project-URL: Homepage, https://ramenai.dev
6
+ Project-URL: Documentation, https://ramenai.dev/llms.txt
7
+ Project-URL: Repository, https://github.com/ramen-ai-dev/ramen-foundry
8
+ License: MIT
9
+ Requires-Python: >=3.10
10
+ Requires-Dist: langchain-core==1.6.0
11
+ Requires-Dist: langgraph==1.2.11
12
+ Requires-Dist: pydantic==2.13.4
13
+ Requires-Dist: ramen-ai-core<0.4.0,>=0.3.2
14
+ Description-Content-Type: text/markdown
15
+
16
+ <p align="center">
17
+ <a href="https://ramenai.dev">
18
+ <img src="https://raw.githubusercontent.com/ramen-ai-dev/ramen-ai-integrations/master/assets/ramen-logo.png" alt="ramen-ai" width="100">
19
+ </a>
20
+ </p>
21
+
22
+ <h1 align="center">ramen-foundry</h1>
23
+
24
+ <p align="center"><strong>Turnkey, legally governed AI agent templates powered by LangGraph and the ramen-ai stateless L2 execution boundary.</strong></p>
25
+
26
+ <p align="center">
27
+ <a href="https://ramenai.dev">Platform</a> ·
28
+ <a href="https://ramenai.dev/pricing">API keys</a> ·
29
+ <a href="https://ramenai.dev/llms.txt">Architecture</a> ·
30
+ <a href="https://github.com/ramen-ai-dev/ramen-ai-integrations">SDKs and integrations</a>
31
+ </p>
32
+
33
+ ---
34
+
35
+ `ramen-foundry` is a Python library of policy-bound LangGraph components and agent templates. It places ramen-ai between model intent and consequential execution, then releases an action only when the semantic verdict allows it **and** the returned Ed25519 receipt verifies locally.
36
+
37
+ Use the low-level nodes to govern an existing graph, or start with a domain template:
38
+
39
+ - **hrtech** — evidence-focused resume review for a human decision-maker.
40
+ - **devbox-shield** — workstation inspection, cleanup, and process control.
41
+ - **db-shield** — database triage, query inspection, and deadlock diagnosis.
42
+ - **scout-shield** — injection-resistant web research and publication.
43
+
44
+ The package supplies governance boundaries and workflow structure; host applications retain ownership of credentials, model adapters, tools, infrastructure permissions, and human approvals. Policy enforcement supports compliance programs but does not by itself constitute legal advice or certification.
45
+
46
+ ## Install
47
+
48
+ ```bash
49
+ pip install ramen-foundry
50
+ ```
51
+
52
+ Python 3.10 or newer is required. Obtain a ramen-ai API key at [ramenai.dev/pricing](https://ramenai.dev/pricing), then provide credentials through your environment or secret manager:
53
+
54
+ ```bash
55
+ export RAMEN_API_KEY="your-ramen-api-key"
56
+ export OPENAI_API_KEY="your-provider-api-key"
57
+ ```
58
+
59
+ Provider keys are required for bring-your-own-key inference unless your ramen-ai enterprise deployment supplies managed credentials. Supported provider routes are `openai`, `anthropic`, `google`, `synthetic`, and `hyperbolic`.
60
+
61
+ ## Five-line quickstart
62
+
63
+ Assume `inspect_directory` is an application-defined LangChain `BaseTool` whose registered name is also `inspect_directory`:
64
+
65
+ ```python
66
+ from os import environ
67
+ from ramen_ai import RamenClient
68
+ from ramen_foundry import DevboxShieldAgent, ToolInvocation
69
+ agent = DevboxShieldAgent(client=RamenClient(environ["RAMEN_API_KEY"]), tools={"inspect_directory": inspect_directory})
70
+ command = agent.execute(ToolInvocation(name="inspect_directory", arguments={"path": "./build"}, tool_call_id="inspect-1"))
71
+ ```
72
+
73
+ `command` routes back to the configured LangGraph `llm_node` (default: `assistant`) with a `ToolMessage`, a cleared invocation, and either `governance_error=None` or an explicit denial/failure reason.
74
+
75
+ ## Core engine architecture
76
+
77
+ ```mermaid
78
+ sequenceDiagram
79
+ participant A as Agent / LangGraph
80
+ participant T as RamenToolNode
81
+ participant R as ramen-ai L2 boundary
82
+ participant C as Host capability
83
+
84
+ A->>T: Resolved ToolInvocation
85
+ T->>T: Canonicalize tool + arguments
86
+ T->>R: Stateless semantic evaluation
87
+ R-->>T: Verdict + Ed25519 receipt
88
+ T->>T: Verify signature and input binding
89
+ alt allowed and receipt_verified
90
+ T->>C: Execute registered BaseTool
91
+ C-->>A: ToolMessage + Command
92
+ else denied, unavailable, or unverifiable
93
+ T-->>A: Error ToolMessage; capability not executed
94
+ end
95
+ ```
96
+
97
+ ### `RamenToolNode`: pre-execution interception
98
+
99
+ `RamenToolNode` is the consequential-action boundary used by all three Shield agents. It:
100
+
101
+ 1. Validates a resolved `ToolInvocation`.
102
+ 2. Serializes `{"tool": name, "arguments": arguments}` as deterministic compact JSON.
103
+ 3. Evaluates that payload against explicit policy UUIDs, stable bundle slugs, or both.
104
+ 4. Requires both `allowed=True` and `receipt_verified=True`.
105
+ 5. Invokes only a registered LangChain `BaseTool`.
106
+ 6. Returns a LangGraph `Command` to the configured model/planner node.
107
+
108
+ Pre-execution failures—evaluation errors, blocked verdicts, missing or invalid receipts, and unknown tools—fail closed before a host capability is invoked. A host tool can still perform a partial side effect before raising an exception; that failure is reported explicitly but cannot be rolled back by Foundry. Safety-significant values must be explicit invocation arguments, and consequential tools should be idempotent or carry operation IDs so callers do not blindly retry an uncertain outcome. Hidden tool-side behavior cannot be semantically evaluated.
109
+
110
+ ### `RamenGovernedNode`: self-correcting generation
111
+
112
+ ```mermaid
113
+ flowchart LR
114
+ P[Prompt] --> G[ramen-ai governed generation]
115
+ G --> M[Provider model]
116
+ M --> E[Semantic evaluation]
117
+ E -->|Needs healing| G
118
+ E -->|Allowed| V[Verified released content]
119
+ E -->|Retry exhausted| B[Blocked; no content released]
120
+ ```
121
+
122
+ `RamenGovernedNode` sends a prompt through the active governed-generation cascade. ramen-ai manages the provider call, semantic evaluation, and one healing retry. Only approved final content is written to graph state. Denials and transport/protocol failures produce `governed_content=None` and an explicit `governance_error`; blocked drafts are never released.
123
+
124
+ The Foundry node is synchronous and non-streaming. The underlying `ramen-ai-core` SDK also exposes streaming governed generation for applications that need progress events.
125
+
126
+ ## Template catalogue
127
+
128
+ | Template | Public class | Bound policy scope | Consequential capabilities |
129
+ |---|---|---|---|
130
+ | `hrtech` | `ResumeScreeningAgent` | EU AI Act Annex III Proxy Bias Interceptor (`0d5ed2af-5e98-4a8c-92c3-dea26c07bf9a`) | Governed evidence-focused report; mandatory human review |
131
+ | `devbox-shield` | `DevboxShieldAgent` | `ramen__shield_core_it`: Destructive Execution, Infrastructure Abuse, Secret Exfiltration | Directory inspection, path deletion, process termination |
132
+ | `db-shield` | `DbShieldAgent` | `ramen__shield_core_it`: Destructive Execution and Infrastructure Abuse | Query/plan inspection, deadlock diagnosis, backend termination |
133
+ | `scout-shield` | `ScoutShieldAgent` | `ramen__shield_core_it`: OWASP ASI06 Indirect Prompt Injection and Secret Exfiltration | URL retrieval, extraction, approved local reads, publication |
134
+
135
+ `ramen__shield_core_it` is an immutable production bundle slug. The backend resolves it to the currently active policy UUIDs at request time; the signed receipt records the exact resolved UUIDs that ran. This lets policy implementations evolve without requiring client releases.
136
+
137
+ ### hrtech
138
+
139
+ `ResumeScreeningAgent` compiles:
140
+
141
+ ```text
142
+ START → draft_review_prompt → governed_resume_review → END
143
+ ```
144
+
145
+ An application-supplied `BaseChatModel` drafts a neutral evidence-collection plan. `RamenGovernedNode` then generates the final report under the fixed Proxy Bias Interceptor. The result never represents a hiring, rejection, ranking, or eligibility decision and always returns `requires_human_review=True`.
146
+
147
+ ```python
148
+ agent = ResumeScreeningAgent(
149
+ llm=chat_model,
150
+ client=client,
151
+ provider_key=provider_key,
152
+ provider_name="openai",
153
+ )
154
+ result = agent.screen(
155
+ ResumeScreeningRequest(
156
+ resume_text="Candidate resume text",
157
+ job_description="Role requirements",
158
+ )
159
+ )
160
+ ```
161
+
162
+ The human-review flag is an application contract, not a built-in LangGraph interrupt or approval UI.
163
+
164
+ ### devbox-shield
165
+
166
+ `DevboxShieldAgent` permits only these host-supplied tool names:
167
+
168
+ | Tool name | Intended capability |
169
+ |---|---|
170
+ | `inspect_directory` | Inspect paths, sizes, and cleanup candidates without mutation. |
171
+ | `delete_path` | Delete a host-approved cache, build output, or other path. |
172
+ | `terminate_process` | Terminate an explicitly identified orphan process. |
173
+
174
+ All requests are evaluated before tool lookup or execution. Attempts to remove system paths, user roots, shell configuration, credential material, or unrelated processes are expected to be denied by the bound Core IT controls. Hosts should additionally constrain deletion roots and process ownership inside their tool implementations.
175
+
176
+ ### db-shield
177
+
178
+ `DbShieldAgent` permits:
179
+
180
+ | Tool name | Intended capability |
181
+ |---|---|
182
+ | `explain_query` | Run `EXPLAIN` through a read-only adapter. |
183
+ | `inspect_deadlocks` | Inspect lock graphs, blockers, and waiters. |
184
+ | `run_query` | Run a parameterized diagnostic/read query. |
185
+ | `terminate_backend` | Invoke a controlled `pg_terminate_backend` adapter. |
186
+
187
+ Query text and parameters are included in the governed payload. Destructive operations such as `DROP TABLE`, `TRUNCATE`, unscoped deletes, and unindexed bulk mutation requests can therefore be intercepted before database execution. Use least-privilege database roles, statement timeouts, transactions, and explicit environment identifiers as defence in depth.
188
+
189
+ ### scout-shield
190
+
191
+ `ScoutShieldAgent` permits:
192
+
193
+ | Tool name | Intended capability |
194
+ |---|---|
195
+ | `fetch_url` | Retrieve an approved web resource. |
196
+ | `extract_content` | Parse or normalize retrieved material. |
197
+ | `read_local_file` | Read an explicitly approved research input. |
198
+ | `publish_research` | Publish an approved research artifact. |
199
+
200
+ Scraped pages, documents, and search results are untrusted input. Requests induced by embedded instructions—such as reading `.env`, collecting cloud credentials, curling secrets to an attacker, or publishing private data—are evaluated against OWASP ASI06 and secret-exfiltration controls before the capability can execute. Do not give research tools ambient access to secrets.
201
+
202
+ ## Operational agent API
203
+
204
+ All three Shield agents share the same constructor and execution shape:
205
+
206
+ ```python
207
+ ShieldAgent(
208
+ *,
209
+ client: RamenClient,
210
+ tools: Mapping[str, BaseTool],
211
+ llm_node: str = "assistant",
212
+ provider_key: str | None = None,
213
+ provider_name: str | None = None,
214
+ )
215
+
216
+ agent.execute(invocation: ToolInvocation | Mapping[str, Any]) -> Command
217
+ agent(state: Mapping[str, Any]) -> Command
218
+ ```
219
+
220
+ - `execute(...)` is convenient for a resolved standalone action.
221
+ - `agent(state)` makes the instance a LangGraph node and expects `state["tool_invocation"]`.
222
+ - `tool_names` returns the sorted registered capability names.
223
+ - Registry keys must match each `BaseTool.name` and must belong to the template's documented capability set.
224
+ - The constructor always binds `bundle_ids=["ramen__shield_core_it"]`; callers cannot weaken or replace that scope.
225
+
226
+ ### BYOK configuration
227
+
228
+ ```python
229
+ agent = ScoutShieldAgent(
230
+ client=RamenClient(os.environ["RAMEN_API_KEY"]),
231
+ tools={"fetch_url": fetch_url},
232
+ provider_key=os.environ["OPENAI_API_KEY"],
233
+ provider_name="openai",
234
+ )
235
+ ```
236
+
237
+ Pass `provider_key` and `provider_name` together. Omit both only when managed provider credentials are provisioned server-side.
238
+
239
+ ## Security guarantees
240
+
241
+ ### Stateless evaluation
242
+
243
+ Each evaluation contains the resolved action, explicit arguments, policy/bundle scope, and minimal context. ramen-ai does not need the agent's mutable LangGraph state to decide whether that action may cross the L2 boundary.
244
+
245
+ ### Pre-execution interception
246
+
247
+ The governance call completes before registered capability lookup and invocation. A blocked action never reaches the host tool. This is materially different from output-only filtering after a shell command, SQL statement, or outbound request has already run.
248
+
249
+ ### Fail-closed mechanics
250
+
251
+ A host tool is invoked only after all pre-execution conditions hold:
252
+
253
+ - The `ToolInvocation` is valid.
254
+ - The evaluation request succeeds.
255
+ - The semantic verdict is affirmative.
256
+ - The V5 receipt is present and cryptographically verified.
257
+ - The receipt's SHA-256 input binding matches the canonical action payload.
258
+ - The tool name is registered for that template.
259
+
260
+ For a valid invocation, governance and tool outcomes return an explicit `governance_error` on failure. Missing or malformed invocation state raises validation before evaluation and cannot execute a capability. Once an approved host tool begins, however, an exception may represent a partial side effect; inspect operation evidence before retrying.
261
+
262
+ ### Ed25519 cryptographic receipts
263
+
264
+ `ramen-ai-core` verifies Ed25519 signatures and input hash binding locally. Receipts bind the verdict to the exact canonical input, resolved policy UUIDs, violations, statutory/control anchors, execution time, and outcome. Foundry requires `receipt_verified=True`; an unsigned or unverifiable allow is treated as a denial.
265
+
266
+ ### Defence in depth
267
+
268
+ Semantic governance is not a replacement for OS permissions, sandboxing, read-only database roles, parameterized SQL, network egress controls, secret isolation, transaction boundaries, backups, human approvals, or application-specific allowlists. Keep those controls in place.
269
+
270
+ ## Public exports
271
+
272
+ ```python
273
+ from ramen_foundry import (
274
+ DbShieldAgent,
275
+ DevboxShieldAgent,
276
+ EU_AI_ACT_PROXY_BIAS_POLICY_ID,
277
+ RamenGovernedNode,
278
+ RamenToolNode,
279
+ ResumeScreeningAgent,
280
+ ResumeScreeningRequest,
281
+ ResumeScreeningResult,
282
+ SHIELD_CORE_IT_BUNDLE_ID,
283
+ ScoutShieldAgent,
284
+ ToolInvocation,
285
+ )
286
+ ```
287
+
288
+ `ToolInvocation` contains a non-empty `name`, an `arguments` dictionary, and a non-empty `tool_call_id`. `RamenToolNode` and `RamenGovernedNode` accept explicit `policy_ids`, `bundle_ids`, or both; at least one scope is required.
289
+
290
+ ## Runtime dependencies
291
+
292
+ | Package | Constraint |
293
+ |---|---:|
294
+ | Python | `>=3.10` |
295
+ | `ramen-ai-core` | `>=0.3.2,<0.4.0` |
296
+ | `langgraph` | `==1.2.11` |
297
+ | `langchain-core` | `==1.6.0` |
298
+ | `pydantic` | `==2.13.4` |
299
+
300
+ ## Resources
301
+
302
+ - [ramen-ai platform](https://ramenai.dev)
303
+ - [Plans and API keys](https://ramenai.dev/pricing)
304
+ - [Machine-readable architecture and integration context](https://ramenai.dev/llms.txt)
305
+ - [Python SDK and integrations](https://github.com/ramen-ai-dev/ramen-ai-integrations)
306
+ - [ramen-foundry source](https://github.com/ramen-ai-dev/ramen-foundry)
307
+
308
+ ## License
309
+
310
+ MIT, as declared in `pyproject.toml`.
@@ -0,0 +1,295 @@
1
+ <p align="center">
2
+ <a href="https://ramenai.dev">
3
+ <img src="https://raw.githubusercontent.com/ramen-ai-dev/ramen-ai-integrations/master/assets/ramen-logo.png" alt="ramen-ai" width="100">
4
+ </a>
5
+ </p>
6
+
7
+ <h1 align="center">ramen-foundry</h1>
8
+
9
+ <p align="center"><strong>Turnkey, legally governed AI agent templates powered by LangGraph and the ramen-ai stateless L2 execution boundary.</strong></p>
10
+
11
+ <p align="center">
12
+ <a href="https://ramenai.dev">Platform</a> ·
13
+ <a href="https://ramenai.dev/pricing">API keys</a> ·
14
+ <a href="https://ramenai.dev/llms.txt">Architecture</a> ·
15
+ <a href="https://github.com/ramen-ai-dev/ramen-ai-integrations">SDKs and integrations</a>
16
+ </p>
17
+
18
+ ---
19
+
20
+ `ramen-foundry` is a Python library of policy-bound LangGraph components and agent templates. It places ramen-ai between model intent and consequential execution, then releases an action only when the semantic verdict allows it **and** the returned Ed25519 receipt verifies locally.
21
+
22
+ Use the low-level nodes to govern an existing graph, or start with a domain template:
23
+
24
+ - **hrtech** — evidence-focused resume review for a human decision-maker.
25
+ - **devbox-shield** — workstation inspection, cleanup, and process control.
26
+ - **db-shield** — database triage, query inspection, and deadlock diagnosis.
27
+ - **scout-shield** — injection-resistant web research and publication.
28
+
29
+ The package supplies governance boundaries and workflow structure; host applications retain ownership of credentials, model adapters, tools, infrastructure permissions, and human approvals. Policy enforcement supports compliance programs but does not by itself constitute legal advice or certification.
30
+
31
+ ## Install
32
+
33
+ ```bash
34
+ pip install ramen-foundry
35
+ ```
36
+
37
+ Python 3.10 or newer is required. Obtain a ramen-ai API key at [ramenai.dev/pricing](https://ramenai.dev/pricing), then provide credentials through your environment or secret manager:
38
+
39
+ ```bash
40
+ export RAMEN_API_KEY="your-ramen-api-key"
41
+ export OPENAI_API_KEY="your-provider-api-key"
42
+ ```
43
+
44
+ Provider keys are required for bring-your-own-key inference unless your ramen-ai enterprise deployment supplies managed credentials. Supported provider routes are `openai`, `anthropic`, `google`, `synthetic`, and `hyperbolic`.
45
+
46
+ ## Five-line quickstart
47
+
48
+ Assume `inspect_directory` is an application-defined LangChain `BaseTool` whose registered name is also `inspect_directory`:
49
+
50
+ ```python
51
+ from os import environ
52
+ from ramen_ai import RamenClient
53
+ from ramen_foundry import DevboxShieldAgent, ToolInvocation
54
+ agent = DevboxShieldAgent(client=RamenClient(environ["RAMEN_API_KEY"]), tools={"inspect_directory": inspect_directory})
55
+ command = agent.execute(ToolInvocation(name="inspect_directory", arguments={"path": "./build"}, tool_call_id="inspect-1"))
56
+ ```
57
+
58
+ `command` routes back to the configured LangGraph `llm_node` (default: `assistant`) with a `ToolMessage`, a cleared invocation, and either `governance_error=None` or an explicit denial/failure reason.
59
+
60
+ ## Core engine architecture
61
+
62
+ ```mermaid
63
+ sequenceDiagram
64
+ participant A as Agent / LangGraph
65
+ participant T as RamenToolNode
66
+ participant R as ramen-ai L2 boundary
67
+ participant C as Host capability
68
+
69
+ A->>T: Resolved ToolInvocation
70
+ T->>T: Canonicalize tool + arguments
71
+ T->>R: Stateless semantic evaluation
72
+ R-->>T: Verdict + Ed25519 receipt
73
+ T->>T: Verify signature and input binding
74
+ alt allowed and receipt_verified
75
+ T->>C: Execute registered BaseTool
76
+ C-->>A: ToolMessage + Command
77
+ else denied, unavailable, or unverifiable
78
+ T-->>A: Error ToolMessage; capability not executed
79
+ end
80
+ ```
81
+
82
+ ### `RamenToolNode`: pre-execution interception
83
+
84
+ `RamenToolNode` is the consequential-action boundary used by all three Shield agents. It:
85
+
86
+ 1. Validates a resolved `ToolInvocation`.
87
+ 2. Serializes `{"tool": name, "arguments": arguments}` as deterministic compact JSON.
88
+ 3. Evaluates that payload against explicit policy UUIDs, stable bundle slugs, or both.
89
+ 4. Requires both `allowed=True` and `receipt_verified=True`.
90
+ 5. Invokes only a registered LangChain `BaseTool`.
91
+ 6. Returns a LangGraph `Command` to the configured model/planner node.
92
+
93
+ Pre-execution failures—evaluation errors, blocked verdicts, missing or invalid receipts, and unknown tools—fail closed before a host capability is invoked. A host tool can still perform a partial side effect before raising an exception; that failure is reported explicitly but cannot be rolled back by Foundry. Safety-significant values must be explicit invocation arguments, and consequential tools should be idempotent or carry operation IDs so callers do not blindly retry an uncertain outcome. Hidden tool-side behavior cannot be semantically evaluated.
94
+
95
+ ### `RamenGovernedNode`: self-correcting generation
96
+
97
+ ```mermaid
98
+ flowchart LR
99
+ P[Prompt] --> G[ramen-ai governed generation]
100
+ G --> M[Provider model]
101
+ M --> E[Semantic evaluation]
102
+ E -->|Needs healing| G
103
+ E -->|Allowed| V[Verified released content]
104
+ E -->|Retry exhausted| B[Blocked; no content released]
105
+ ```
106
+
107
+ `RamenGovernedNode` sends a prompt through the active governed-generation cascade. ramen-ai manages the provider call, semantic evaluation, and one healing retry. Only approved final content is written to graph state. Denials and transport/protocol failures produce `governed_content=None` and an explicit `governance_error`; blocked drafts are never released.
108
+
109
+ The Foundry node is synchronous and non-streaming. The underlying `ramen-ai-core` SDK also exposes streaming governed generation for applications that need progress events.
110
+
111
+ ## Template catalogue
112
+
113
+ | Template | Public class | Bound policy scope | Consequential capabilities |
114
+ |---|---|---|---|
115
+ | `hrtech` | `ResumeScreeningAgent` | EU AI Act Annex III Proxy Bias Interceptor (`0d5ed2af-5e98-4a8c-92c3-dea26c07bf9a`) | Governed evidence-focused report; mandatory human review |
116
+ | `devbox-shield` | `DevboxShieldAgent` | `ramen__shield_core_it`: Destructive Execution, Infrastructure Abuse, Secret Exfiltration | Directory inspection, path deletion, process termination |
117
+ | `db-shield` | `DbShieldAgent` | `ramen__shield_core_it`: Destructive Execution and Infrastructure Abuse | Query/plan inspection, deadlock diagnosis, backend termination |
118
+ | `scout-shield` | `ScoutShieldAgent` | `ramen__shield_core_it`: OWASP ASI06 Indirect Prompt Injection and Secret Exfiltration | URL retrieval, extraction, approved local reads, publication |
119
+
120
+ `ramen__shield_core_it` is an immutable production bundle slug. The backend resolves it to the currently active policy UUIDs at request time; the signed receipt records the exact resolved UUIDs that ran. This lets policy implementations evolve without requiring client releases.
121
+
122
+ ### hrtech
123
+
124
+ `ResumeScreeningAgent` compiles:
125
+
126
+ ```text
127
+ START → draft_review_prompt → governed_resume_review → END
128
+ ```
129
+
130
+ An application-supplied `BaseChatModel` drafts a neutral evidence-collection plan. `RamenGovernedNode` then generates the final report under the fixed Proxy Bias Interceptor. The result never represents a hiring, rejection, ranking, or eligibility decision and always returns `requires_human_review=True`.
131
+
132
+ ```python
133
+ agent = ResumeScreeningAgent(
134
+ llm=chat_model,
135
+ client=client,
136
+ provider_key=provider_key,
137
+ provider_name="openai",
138
+ )
139
+ result = agent.screen(
140
+ ResumeScreeningRequest(
141
+ resume_text="Candidate resume text",
142
+ job_description="Role requirements",
143
+ )
144
+ )
145
+ ```
146
+
147
+ The human-review flag is an application contract, not a built-in LangGraph interrupt or approval UI.
148
+
149
+ ### devbox-shield
150
+
151
+ `DevboxShieldAgent` permits only these host-supplied tool names:
152
+
153
+ | Tool name | Intended capability |
154
+ |---|---|
155
+ | `inspect_directory` | Inspect paths, sizes, and cleanup candidates without mutation. |
156
+ | `delete_path` | Delete a host-approved cache, build output, or other path. |
157
+ | `terminate_process` | Terminate an explicitly identified orphan process. |
158
+
159
+ All requests are evaluated before tool lookup or execution. Attempts to remove system paths, user roots, shell configuration, credential material, or unrelated processes are expected to be denied by the bound Core IT controls. Hosts should additionally constrain deletion roots and process ownership inside their tool implementations.
160
+
161
+ ### db-shield
162
+
163
+ `DbShieldAgent` permits:
164
+
165
+ | Tool name | Intended capability |
166
+ |---|---|
167
+ | `explain_query` | Run `EXPLAIN` through a read-only adapter. |
168
+ | `inspect_deadlocks` | Inspect lock graphs, blockers, and waiters. |
169
+ | `run_query` | Run a parameterized diagnostic/read query. |
170
+ | `terminate_backend` | Invoke a controlled `pg_terminate_backend` adapter. |
171
+
172
+ Query text and parameters are included in the governed payload. Destructive operations such as `DROP TABLE`, `TRUNCATE`, unscoped deletes, and unindexed bulk mutation requests can therefore be intercepted before database execution. Use least-privilege database roles, statement timeouts, transactions, and explicit environment identifiers as defence in depth.
173
+
174
+ ### scout-shield
175
+
176
+ `ScoutShieldAgent` permits:
177
+
178
+ | Tool name | Intended capability |
179
+ |---|---|
180
+ | `fetch_url` | Retrieve an approved web resource. |
181
+ | `extract_content` | Parse or normalize retrieved material. |
182
+ | `read_local_file` | Read an explicitly approved research input. |
183
+ | `publish_research` | Publish an approved research artifact. |
184
+
185
+ Scraped pages, documents, and search results are untrusted input. Requests induced by embedded instructions—such as reading `.env`, collecting cloud credentials, curling secrets to an attacker, or publishing private data—are evaluated against OWASP ASI06 and secret-exfiltration controls before the capability can execute. Do not give research tools ambient access to secrets.
186
+
187
+ ## Operational agent API
188
+
189
+ All three Shield agents share the same constructor and execution shape:
190
+
191
+ ```python
192
+ ShieldAgent(
193
+ *,
194
+ client: RamenClient,
195
+ tools: Mapping[str, BaseTool],
196
+ llm_node: str = "assistant",
197
+ provider_key: str | None = None,
198
+ provider_name: str | None = None,
199
+ )
200
+
201
+ agent.execute(invocation: ToolInvocation | Mapping[str, Any]) -> Command
202
+ agent(state: Mapping[str, Any]) -> Command
203
+ ```
204
+
205
+ - `execute(...)` is convenient for a resolved standalone action.
206
+ - `agent(state)` makes the instance a LangGraph node and expects `state["tool_invocation"]`.
207
+ - `tool_names` returns the sorted registered capability names.
208
+ - Registry keys must match each `BaseTool.name` and must belong to the template's documented capability set.
209
+ - The constructor always binds `bundle_ids=["ramen__shield_core_it"]`; callers cannot weaken or replace that scope.
210
+
211
+ ### BYOK configuration
212
+
213
+ ```python
214
+ agent = ScoutShieldAgent(
215
+ client=RamenClient(os.environ["RAMEN_API_KEY"]),
216
+ tools={"fetch_url": fetch_url},
217
+ provider_key=os.environ["OPENAI_API_KEY"],
218
+ provider_name="openai",
219
+ )
220
+ ```
221
+
222
+ Pass `provider_key` and `provider_name` together. Omit both only when managed provider credentials are provisioned server-side.
223
+
224
+ ## Security guarantees
225
+
226
+ ### Stateless evaluation
227
+
228
+ Each evaluation contains the resolved action, explicit arguments, policy/bundle scope, and minimal context. ramen-ai does not need the agent's mutable LangGraph state to decide whether that action may cross the L2 boundary.
229
+
230
+ ### Pre-execution interception
231
+
232
+ The governance call completes before registered capability lookup and invocation. A blocked action never reaches the host tool. This is materially different from output-only filtering after a shell command, SQL statement, or outbound request has already run.
233
+
234
+ ### Fail-closed mechanics
235
+
236
+ A host tool is invoked only after all pre-execution conditions hold:
237
+
238
+ - The `ToolInvocation` is valid.
239
+ - The evaluation request succeeds.
240
+ - The semantic verdict is affirmative.
241
+ - The V5 receipt is present and cryptographically verified.
242
+ - The receipt's SHA-256 input binding matches the canonical action payload.
243
+ - The tool name is registered for that template.
244
+
245
+ For a valid invocation, governance and tool outcomes return an explicit `governance_error` on failure. Missing or malformed invocation state raises validation before evaluation and cannot execute a capability. Once an approved host tool begins, however, an exception may represent a partial side effect; inspect operation evidence before retrying.
246
+
247
+ ### Ed25519 cryptographic receipts
248
+
249
+ `ramen-ai-core` verifies Ed25519 signatures and input hash binding locally. Receipts bind the verdict to the exact canonical input, resolved policy UUIDs, violations, statutory/control anchors, execution time, and outcome. Foundry requires `receipt_verified=True`; an unsigned or unverifiable allow is treated as a denial.
250
+
251
+ ### Defence in depth
252
+
253
+ Semantic governance is not a replacement for OS permissions, sandboxing, read-only database roles, parameterized SQL, network egress controls, secret isolation, transaction boundaries, backups, human approvals, or application-specific allowlists. Keep those controls in place.
254
+
255
+ ## Public exports
256
+
257
+ ```python
258
+ from ramen_foundry import (
259
+ DbShieldAgent,
260
+ DevboxShieldAgent,
261
+ EU_AI_ACT_PROXY_BIAS_POLICY_ID,
262
+ RamenGovernedNode,
263
+ RamenToolNode,
264
+ ResumeScreeningAgent,
265
+ ResumeScreeningRequest,
266
+ ResumeScreeningResult,
267
+ SHIELD_CORE_IT_BUNDLE_ID,
268
+ ScoutShieldAgent,
269
+ ToolInvocation,
270
+ )
271
+ ```
272
+
273
+ `ToolInvocation` contains a non-empty `name`, an `arguments` dictionary, and a non-empty `tool_call_id`. `RamenToolNode` and `RamenGovernedNode` accept explicit `policy_ids`, `bundle_ids`, or both; at least one scope is required.
274
+
275
+ ## Runtime dependencies
276
+
277
+ | Package | Constraint |
278
+ |---|---:|
279
+ | Python | `>=3.10` |
280
+ | `ramen-ai-core` | `>=0.3.2,<0.4.0` |
281
+ | `langgraph` | `==1.2.11` |
282
+ | `langchain-core` | `==1.6.0` |
283
+ | `pydantic` | `==2.13.4` |
284
+
285
+ ## Resources
286
+
287
+ - [ramen-ai platform](https://ramenai.dev)
288
+ - [Plans and API keys](https://ramenai.dev/pricing)
289
+ - [Machine-readable architecture and integration context](https://ramenai.dev/llms.txt)
290
+ - [Python SDK and integrations](https://github.com/ramen-ai-dev/ramen-ai-integrations)
291
+ - [ramen-foundry source](https://github.com/ramen-ai-dev/ramen-foundry)
292
+
293
+ ## License
294
+
295
+ MIT, as declared in `pyproject.toml`.
@@ -0,0 +1,28 @@
1
+ [build-system]
2
+ requires = ["hatchling==1.32.0"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "ramen-foundry"
7
+ version = "0.1.1"
8
+ description = "LangGraph governance nodes and human-review workflow templates powered by ramen-ai."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = { text = "MIT" }
12
+ dependencies = [
13
+ "ramen-ai-core>=0.3.2,<0.4.0",
14
+ "langgraph==1.2.11",
15
+ "langchain-core==1.6.0",
16
+ "pydantic==2.13.4",
17
+ ]
18
+
19
+ [project.urls]
20
+ Homepage = "https://ramenai.dev"
21
+ Documentation = "https://ramenai.dev/llms.txt"
22
+ Repository = "https://github.com/ramen-ai-dev/ramen-foundry"
23
+
24
+ [tool.hatch.build.targets.wheel]
25
+ packages = ["ramen_foundry"]
26
+
27
+ [tool.pytest.ini_options]
28
+ testpaths = ["tests"]
@@ -0,0 +1,29 @@
1
+ """Ramen Foundry: LangGraph governance nodes and workflow templates."""
2
+
3
+ from .core import RamenGovernedNode, RamenToolNode, ToolInvocation
4
+ from .templates import (
5
+ DbShieldAgent,
6
+ DevboxShieldAgent,
7
+ EU_AI_ACT_PROXY_BIAS_POLICY_ID,
8
+ ResumeScreeningAgent,
9
+ ResumeScreeningRequest,
10
+ ResumeScreeningResult,
11
+ SHIELD_CORE_IT_BUNDLE_ID,
12
+ ScoutShieldAgent,
13
+ )
14
+
15
+ __all__ = [
16
+ "DbShieldAgent",
17
+ "DevboxShieldAgent",
18
+ "EU_AI_ACT_PROXY_BIAS_POLICY_ID",
19
+ "RamenGovernedNode",
20
+ "RamenToolNode",
21
+ "ResumeScreeningAgent",
22
+ "ResumeScreeningRequest",
23
+ "ResumeScreeningResult",
24
+ "SHIELD_CORE_IT_BUNDLE_ID",
25
+ "ScoutShieldAgent",
26
+ "ToolInvocation",
27
+ ]
28
+
29
+ __version__ = "0.1.1"
@@ -0,0 +1,5 @@
1
+ """Low-level LangGraph governance nodes."""
2
+
3
+ from .langgraph_nodes import RamenGovernedNode, RamenToolNode, ToolInvocation
4
+
5
+ __all__ = ["RamenGovernedNode", "RamenToolNode", "ToolInvocation"]