crates/monty-proto/README.md
The wire protocol connecting Monty worker processes to the parents that drive them.
Monty executes untrusted Python, and a Monty process can never be made fully
crash-proof against memory errors (stack overflow aborts, allocator aborts —
the monty-alloc allocator turns the
latter into this crate's OOM_EXIT_CODE so a parent can classify them).
The subprocess architecture isolates those crashes: a parent — the
monty-pool crate, and through it the
Python and JavaScript packages — drives monty subprocess children over
framed stdio (or a WebSocket), and a dead child is simply replaced. This crate
defines the protocol both sides speak.
The protocol is protobuf (rather than Monty's internal postcard format) so a
parent or child can be implemented in any language — see
proto/monty/v1/monty.proto
for the schema and the protocol rules documented alongside it.
pb — prost-generated message types. The generated code is checked in;
regenerate with make generate-proto (CI enforces sync via
make check-proto).FrameReader / write_frame — 4-byte little-endian length-prefixed
framing, with a hard cap on frame length.pb types and Monty's public types
(MontyObject, MontyException, mounts, resource limits, ...).PROTOCOL_VERSION / MIN_SUPPORTED_PROTOCOL_VERSION — the wire schema
version a parent declares in Configure, and the range a child serves.
Versioned independently of the monty package: peers on different releases
interoperate as long as their protocol versions overlap. There is no in-band
negotiation, so a child rejecting a version reports its range in the
FatalError for the parent to downgrade to.python (cargo feature, off by default) — the python module: PyO3-based
conversions between live Python objects and MontyObject/MontyException,
used by the pydantic-monty-client extension module. The feature pulls in pyo3 (but never its
extension-module feature — how libpython is linked stays the top crate's
decision), so pure-Rust consumers pay nothing for it.The monty.v1.MontyObject message is mapped via prost extern_path onto
WireObject: a hand-written prost::Message implementation that encodes
borrowed MontyObjects and validates while decoding — no mirror struct and
no deep clone on the hot path. tests/differential.rs proves it
byte-compatible against a fully prost-generated oracle (tests/oracle/,
regenerated and CI-checked together with the main codegen).
A parent must treat every frame from a (possibly compromised) child as untrusted input: conversions from proto to Rust are fallible by design, decoding enforces depth and size budgets, and nothing in this crate panics on malformed wire data.
This crate includes the worker feature and module
A transport-agnostic Monty protocol-child state machine, shared by the native subprocess and the wasm worker.
monty — the core interpreter: Python parser, bytecode VM, and sandbox.monty-types — the shared boundary data types (values, exceptions, OS calls, resource limits) hosts use without linking the interpreter.monty-fs — host-side filesystem mounts: maps virtual sandbox paths to real host directories.monty-runtime — the monty binary: REPL, file runner, and subprocess worker mode.monty-pool — an elastic pool of crash-isolated monty worker subprocesses.monty-proto — the protobuf wire protocol spoken between pool parents and workers. this cratemonty-type-checking — type checking of sandboxed code, powered by ty.monty-typeshed — the trimmed typeshed stubs describing the stdlib subset Monty implements.monty-macros — the proc macros behind monty's argument parsing.