Skip to content

Sandbox DSL spec execution via pydantic-monty - #1

Open
michaelballantyne wants to merge 1 commit into
lanl:agoosh-ddsl-mcpfrom
michaelballantyne:claude/sandboxed-dsl-execution
Open

Sandbox DSL spec execution via pydantic-monty#1
michaelballantyne wants to merge 1 commit into
lanl:agoosh-ddsl-mcpfrom
michaelballantyne:claude/sandboxed-dsl-execution

Conversation

@michaelballantyne

Copy link
Copy Markdown
Collaborator

run_pipeline previously ran agent-authored spec.py with a bare exec(compile(...)), giving untrusted DSL code full host access. Run it inside pydantic-monty instead.

  • sandbox.py: execute(code, namespace) runs the spec in a MontyRepl with resource limits and a restricted import/builtin surface, and returns the top-level bindings (shape-equivalent to the old post-exec namespace). Form nodes are marshalled across the boundary as opaque NodeHandle ids (host keeps the real Node table) so deep upstream chains don't re-serialize and forged/mutated handles are rejected. Forms register under their real names (none collide with a Monty builtin), so specs still need no imports.
  • mcp_server.run_pipeline: call sandbox.execute(); surface SandboxError / SyntaxError as BUILD FAILED. reset_sinks/collected_sinks/leaf_nodes and the dry-run/report logic are unchanged.
  • tests/test_sandbox.py: plain-python asserts (no numpy) covering build, kwargs, dry-run recovery, error surfacing, security blocks, and forgery.
  • requirements.txt: declare the new pydantic-monty dependency.

Claude-Session: https://claude.ai/code/session_01EiiXjxvhep4tZXmnwRqe8H

run_pipeline previously ran agent-authored spec.py with a bare
exec(compile(...)), giving untrusted DSL code full host access. Run it
inside pydantic-monty instead.

- sandbox.py: execute(code, namespace) runs the spec in a MontyRepl with
  resource limits and a restricted import/builtin surface, and returns the
  top-level bindings (shape-equivalent to the old post-exec namespace).
  Form nodes are marshalled across the boundary as opaque NodeHandle ids
  (host keeps the real Node table) so deep upstream chains don't re-serialize
  and forged/mutated handles are rejected. Forms register under their real
  names (none collide with a Monty builtin), so specs still need no imports.
- mcp_server.run_pipeline: call sandbox.execute(); surface SandboxError /
  SyntaxError as BUILD FAILED. reset_sinks/collected_sinks/leaf_nodes and the
  dry-run/report logic are unchanged.
- tests/test_sandbox.py: plain-python asserts (no numpy) covering build,
  kwargs, dry-run recovery, error surfacing, security blocks, and forgery.
- requirements.txt: declare the new pydantic-monty dependency.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EiiXjxvhep4tZXmnwRqe8H
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants