diff --git a/README.md b/README.md index 34db9be..eb9ded8 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,10 @@ or CAN and radio injection, raises `simantic.NotSupported` and names the gap instead of quietly doing nothing. You can follow what each engine covers in [simantic-core#183](https://github.com/simantic-dev/simantic-core/issues/183). +This `backend=` dispatch is meant to be the one place engine choice happens — +see [`docs/unified-surface.md`](docs/unified-surface.md) for where the CLI and +MCP install are expected to grow the same logic. + ## Testing with pytest Take the `sim` fixture and write ordinary tests: diff --git a/docs/session-api.md b/docs/session-api.md index cb94582..0f68846 100644 --- a/docs/session-api.md +++ b/docs/session-api.md @@ -106,3 +106,6 @@ an agent that needs a loop, is better served by code: the loop runs in the engine's process, only the conclusion enters the transcript, and the script becomes a fixture. `Sim` is that path; the MCP servers remain for interactive poking and are expected to shrink to a thin adapter over it. + +See [`unified-surface.md`](unified-surface.md) for where the CLI dispatch and +an eventual unified MCP server's client-side install are expected to land. diff --git a/docs/unified-surface.md b/docs/unified-surface.md new file mode 100644 index 0000000..67cad7f --- /dev/null +++ b/docs/unified-surface.md @@ -0,0 +1,48 @@ +# Where the unified surface lands + +This package (`pip install simantic`) is already the front door for the +engines: it locates and installs the Renode and Rust binaries, and `Sim` +dispatches between them by `backend=`. Two extensions of that same role are +planned but not yet built. Recording them here so the direction is written +down before the code is. + +## The `Sim` dispatch API grows into the CLI's job too + +`Sim(backend="renode"|"rust")` already picks an engine per call from Python. +Today nothing on the command line does the equivalent — `simantic`/`smtc` +only wraps `auth`/`install`/`status`, and running a simulation from a shell +means invoking the engine's own binary directly (`sim ...`) with no backend +choice at that layer. + +The plan is for `simantic`/`smtc` to grow the same dispatch `Sim` already has, +instead of engines each keeping a separate CLI surface. Concretely: the +`backend=` selection and the `NotSupported`-with-a-named-gap behavior that +`Sim` already implements become the one place that decision is made, called +from both the Python API and the command line, rather than duplicated if a +CLI grows its own copy. + +## The MCP install front door + +Two MCP servers exist today, one per engine, and neither is reachable from +this package: `pyrite-mcp` (Rust engine, active) and the Renode engine's MCP +server (stale). The two engines have genuinely different capabilities — e.g. +Renode's `gdb_*` control plane and multi-machine/CAN/radio scenarios don't +exist on the Rust side — so unifying them isn't one server absorbing the +other's tools; it's a `Sim(backend=...)`-shaped front door that dispatches +each call to whichever engine implements it. Per +[`session-api.md`](session-api.md#why-not-mcp), the MCP servers are expected +to shrink into thin adapters over `Sim` as that dispatch layer takes shape. + +This package is the natural client-side install point for whichever unified +MCP server results, for the same reason it already installs the engines +instead of asking a user to find them: `install.py` already has the +"locate this pinned binary, fetch it if missing, verify it against a +checksum" logic (`install_engine`, `install_rust_engine`). An MCP server +binary is one more thing of that shape — `simantic install mcp` mirrors +`simantic install engine`, and `simantic mcp` launches what it resolved, the +same relationship `Sim` has to the simulation binaries today. + +This package still would not *implement* the MCP server — that stays where +the engine code lives — it would only be the thing a user runs `pip install` +for and then finds the server through, the same boundary that already holds +for the simulation engines.