dimensionalOS / dimensionalOS/dimos
Proposal: Module deployment as Grounded Blueprints
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 4.5k
- Forks
- 808
- Avg merge
- 3d 5h
- Merged PRs (30d)
- 233
Description
Status: draft for review.
This is a proposal/RFC issue.
This note frames PR #2704 as one concrete step toward a broader module deployment model. The goal is not only Python dependency isolation. The larger goal is to let DimOS keep a stable module identity while different implementations run locally, remotely, or as native processes.
Problem
DimOS has two parallel module families today:
- Python modules run through Python workers and get the full DimOS surface: streams, RPCs, skills, module refs, lifecycle, and blueprint wiring.
- Native modules run as external binaries wrapped by a Python
NativeModule. The Python wrapper owns blueprint wiring, lifecycle, topic assignment, config serialization, logging, and process supervision. The native process owns computation and pub/sub.
Both families are moving toward the same deployment pressure:
- Python modules need isolated dependency environments.
- Native modules need repeatable build and runtime environments.
- Remote deployment needs code or binary sync.
- Weak robot computers may need cross-compilation or prepared artifacts.
- Native runtimes may need dynamic libraries, Nix closures, Pixi environments, or transport-specific setup.
The common problem is module deployment.
Current proof point
PR #2704 introduces a narrow proof point for Python modules:
- A blueprint can register a Python runtime project.
- A module contract can be placed into that runtime.
- Deployment reconciles the locked runtime project before launch.
WorkerManagerPythondispatches placed modules into runtime-specific Python worker pools.- The worker launches the prepared
.venv/bin/pythonand imports the runtime implementation. - The coordinator still sees the dependency-light module contract.
That gives us one concrete backend for a broader model: the module contract stays stable while execution moves into a backend-specific runtime.
Native branches point in the same direction
Recent native-module branches show the same shape from another angle:
- Andrew's
cpp-native-module-stdinwork makes native config and topics serializable through stdin instead of only CLI flags. - Andrew's Rust transport work adds a native transport abstraction, including Zenoh.
- Lesh's MLS/RPP work uses Rust native modules with
cargo build --releaseandstdin_config=True.
Those branches are not the same feature as PR #2704, but they point at the same seam: DimOS needs a shared way to describe what a module is, what it needs, where it runs, and how deployment prepares it.
Core concepts
flowchart TD
Package[Self-Contained Module Package]
Contract[Module Contract]
Impl[Implementation]
Requirement[Runtime Requirement]
Recipe[Preparation / Launch Recipes]
Blueprint[Blueprint\nungrounded scaffold]
Grounded[Grounded Blueprint?\nrunnable binding]
Target[Execution Target Profile]
Assignment[Deployment Assignment]
Strategy[Preparation Strategy]
Reconciler[Deployment Reconciler]
Package --> Contract
Package --> Impl
Package --> Requirement
Package --> Recipe
Blueprint --> Grounded
Package --> Grounded
Target --> Grounded
Assignment --> Grounded
Strategy --> Grounded
Grounded --> Reconciler
Reconciler --> Prepare[prepare / build]
Reconciler --> Sync[sync code, binary, or closure]
Reconciler --> Launch[launch process]
Reconciler --> Connect[connect streams, RPC, transports]
Self-Contained Module Package
A Self-Contained Module Package is the module-owned side of deployment. It carries the facts that should move with the module:
- the dependency-light module contract
- the Python implementation or native source/binary target
- runtime and build declarations such as
pyproject.toml,uv.lock,pixi.toml,flake.nix,Cargo.toml, orCMakeLists.txt - preparation recipes
- launch recipe
- optional smoke test
This should start as a layout convention, not a required manifest. Existing Python and native modules already have most of this structure.
Blueprint
A Blueprint should remain the ungrounded scaffold:
- which modules exist
- how streams and refs connect
- what config surfaces exist
- which module contracts participate in the stack
A Blueprint may contain portable deployment intent, but it should not hardcode one lab's SSH hosts, paths, credentials, or robot names.
Grounded Blueprint vs DeploymentSpec
The runnable binding needs a name. The current leaning is Grounded Blueprint rather than DeploymentSpec.
Reason:
Blueprintreads as an architectural scaffold.- A runnable stack needs that scaffold grounded into real targets, assignments, and preparation choices.
DeploymentSpecsounds like a separate ops artifact, while the current project already uses Python-configurable blueprints.
Open question: is Grounded Blueprint the right term, or should we keep DeploymentSpec for the lower-level resolved object?
Execution Target Profile
An Execution Target Profile is the machine-owned side of deployment. It should stay small.
It should include facts we cannot infer from the module package:
- target identity
- access kind: local, SSH, container, Kubernetes, etc.
- architecture and OS family
- deployment root and cache root
- network identity and transport reachability
- hard constraints such as read-only filesystem or no container runtime
It should not become an inventory of installable tools. If uv, pixi, nix, or cargo can be bootstrapped by the deployment workflow, the module package or preparation strategy should say how.
Preparation Strategy
Preparation Strategy is deployment-owned. It decides where and how to realize the module package's runtime requirement for a target.
Examples:
- prepare directly on the execution target
- sync source, then build remotely
- build on the coordinator host, then sync artifacts
- cross-compile on a builder, then sync the binary
- build a Nix closure, then copy the closure
- use a prebuilt artifact
Sync belongs inside the preparation strategy. Sync only makes sense relative to where preparation happens.
Stress-test cases
flowchart LR
subgraph Case1[Python module]
Pkg1[Python package\npyproject + uv/pixi/nix] --> Prep1[prepare on target]
Prep1 --> Run1[run Python implementation]
end
subgraph Case2[Normal native module]
Pkg2[Native package\nCargo / flake / pixi] --> Prep2[build on target]
Prep2 --> Run2[run native binary]
end
subgraph Case3[Weak target native module]
Pkg3[Native package] --> Prep3[cross-compile elsewhere]
Prep3 --> Sync3[sync binary]
Sync3 --> Run3[run on weak target]
end
subgraph Case4[Native binary plus runtime env]
Pkg4[Native package\nsource + runtime env] --> Prep4[cross-compile binary]
Pkg4 --> Env4[prepare/sync runtime closure]
Prep4 --> Run4[run binary]
Env4 --> Run4
end
These cases argue for three separate concerns:
- the module-owned package and requirements
- the target-owned machine profile
- the deployment-owned assignment and preparation strategy
How this maps to current PR #2704
flowchart TD
Contract[Module Contract\ncoordinator-visible identity]
RuntimeImpl[Runtime Implementation\nsubclasses contract]
RuntimeProject[Python Runtime Project\npyproject.toml + uv.lock]
Placement[RuntimePlacement\ncontract -> runtime + implementation]
Blueprint[Blueprint]
Manager[WorkerManagerPython]
Pool[Runtime Python Worker Pool]
Launcher[CommandWorkerLauncher]
Venv[prepared .venv/bin/python]
Worker[python_worker._worker_entrypoint]
Contract --> Blueprint
RuntimeImpl --> RuntimeProject
RuntimeProject --> Placement
Placement --> Blueprint
Blueprint --> Manager
Manager --> Pool
Pool --> Launcher
RuntimeProject --> Venv
Venv --> Launcher
Launcher --> Worker
Worker --> RuntimeImpl
Contract -. RPC / streams / refs .-> Manager
The PR implements one local preparation strategy:
Python runtime project + prepare locally + launch prepared .venv Python
The broader model should let native modules and remote modules reuse the same shape without forcing them into Python runtime terminology.
Proposed direction
Start with Python APIs and conventions rather than a new declarative manifest.
Near term:
Blueprint
remains the Python-configurable module scaffold
Self-Contained Module Package convention
describes module-owned requirements and recipes
Grounded Blueprint? / DeploymentSpec?
binds blueprint modules to targets and preparation strategies
Deployment Reconciler
prepares, syncs, launches, and connects modules
Later:
dimos prepare <grounded-blueprint>
dimos run <grounded-blueprint>
For backward compatibility, a plain Blueprint can be implicitly grounded to the local target.
Open questions
- Should the runnable binding be called Grounded Blueprint or
DeploymentSpec? - How much portable deployment intent should remain on
Blueprintitself? - What is the smallest useful Execution Target Profile?
- Should each Self-Contained Module Package eventually get a manifest, or should layout conventions be enough?
- How should a Deployment Reconciler report the resolved plan before mutating remote machines?
- What native capabilities need the same contract boundary: config, transport descriptors, RPC/control plane, TF, logging, health?
Suggested narrative
Use this PR as a proof point, not as the whole story:
PR #2704 adds local Python runtime projects. More importantly, it introduces a seam between what DimOS sees and where a module implementation runs. That seam can grow into a shared deployment model for Python modules, native modules, and remote execution.
Links
- PR #2704: dimensionalOS/dimos#2704
- Demo command:
uv run python examples/dimos-demo-worker-module/demo_run_blueprint.py
Synced from DIM-1123 by che
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading PR #2704 and its Python runtime placement flow, then run the demo command uv run python examples/dimos-demo-worker-module/demo_run_blueprint.py to understand the current proof point. The work is not yet defined as an implementation task; it would need a decided deployment model, terminology, boundaries, and an agreed definition of done for the open questions.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cmake, kubernetes, python, rust
- Domain
- devops, infrastructure
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100