You are working on MirrorNeuron, an Elixir/BEAM runtime for long-lived, message-driven multi-agent workflows.
Read this file before making changes. Follow the existing codebase closely and prefer small, idiomatic edits over broad rewrites.
- Unless the user explicitly asks for a temporary workaround, fix the root cause in the intended layer or contract.
- Avoid adding fallback paths, compatibility shims, feature flags, or temp solutions that mask a broken primary path.
- If fallback behavior is already product-specified, keep it narrow, documented, and tested; do not use it to avoid fixing the primary path.
- Match existing project conventions before introducing new structure.
- Inspect adjacent code, tests, and docs before editing.
- Do not assume a library, framework pattern, or dependency is appropriate just because it is common elsewhere.
- Do not add new dependencies unless the user explicitly asks or the current approach is clearly impossible.
- Keep comments sparse and high value. Explain why, not what.
- Do not revert unrelated local changes.
- Finish the loop when practical: code, tests, formatting, and brief docs updates if behavior changed.
MirrorNeuron is built around a strict boundary:
- BEAM handles orchestration, supervision, routing, clustering, persistence, and observability.
- Isolated execution is delegated to the sandbox / OpenShell path used by
executornodes.
The runtime is intentionally small and generic. It is not a home for product-specific agents.
- Agents are long-lived processes.
- Workflows are defined by manifest-driven graphs.
- Messages are explicit envelopes.
- Supervision is preferred over defensive complexity.
- CLI and operator visibility matter as much as raw execution.
MirrorNeuron already includes:
- built-in primitives:
router,executor,aggregator,sensor - agent templates:
generic,stream,map,reduce,batch,accumulator - Redis-backed persistence for job state, snapshots, and event history
- cluster support through
libclusterandHorde - a terminal-first CLI and monitor flow
Prefer extending the existing primitives and templates before inventing new top-level concepts.
Important paths:
mix.exs: project config and dependencieslib/mirror_neuron/application.ex: OTP application startuplib/mirror_neuron.ex: public runtime-facing APIlib/mirror_neuron/manifest.ex: manifest loading, normalization, and validationlib/mirror_neuron/message.ex: runtime message envelope shapelib/mirror_neuron/job_bundle.ex: job bundle loadinglib/mirror_neuron/runtime/: job coordinator, supervisors, event bus, runtime wiringlib/mirror_neuron/builtins/: runtime primitives such as router/executor/aggregator/sensorlib/mirror_neuron/agent_templates/: reusable workflow behavior templateslib/mirror_neuron/cluster/: cluster membership and controllib/mirror_neuron/persistence/redis_store.ex: persistence adapterlib/mirror_neuron/sandbox/: sandbox and OpenShell integrationlib/mirror_neuron/execution/: execution lease managementlib/mirror_neuron_grpc/: generated protobuf modules and gRPC service handlersproto/: protobuf service definitionsscripts/: local, cluster, Redis, and release helper scriptstests/: ExUnit coverage for runtime, gRPC, manifests, persistence, runners, clustering, and templates
The active CLI and larger user/operator docs live in sibling ecosystem repositories, not in this checkout.
If the request is about manifests:
- inspect
lib/mirror_neuron/manifest.ex - inspect
lib/mirror_neuron/job_bundle.ex - inspect
tests/mirror_neuron/manifest_test.exs - update example bundles if manifest semantics change
If the request is about runtime lifecycle, job states, or supervision:
- inspect
lib/mirror_neuron/runtime/job_coordinator.ex - inspect
lib/mirror_neuron/runtime/job_runner.ex - inspect
lib/mirror_neuron/runtime/agent_worker.ex - inspect
lib/mirror_neuron/runtime/job_supervisor.ex - inspect
tests/mirror_neuron/runtime_test.exs
If the request is about built-in agent behavior:
- inspect
lib/mirror_neuron/builtins/ - inspect
lib/mirror_neuron/agent_templates/ - inspect
tests/mirror_neuron/agent_templates_test.exs - keep the runtime generic; avoid domain-specific built-ins
If the request is about CLI behavior:
- confirm whether the requested behavior belongs in this core runtime or the external CLI repository
- inspect gRPC/public API behavior here only when the core service contract is involved
If the request is about persistence or recovery:
- inspect
lib/mirror_neuron/persistence/redis_store.ex - inspect
lib/mirror_neuron/redis.ex - inspect runtime coordinator and event bus interactions
If the request is about clustering or remote control:
- inspect
lib/mirror_neuron/cluster/ - inspect
lib/mirror_neuron/distributed_registry.ex - inspect
lib/mirror_neuron/rpc.ex
If the request is about sandboxed execution:
- inspect
lib/mirror_neuron/sandbox/ - inspect
lib/mirror_neuron/execution/lease_manager.ex - inspect
lib/mirror_neuron/builtins/executor.ex
- Keep blueprint-specific system packages in the blueprint's custom OpenShell image, not in the core Docker image.
- When an OpenShell agent must call a private or LAN service, the policy must usually include
allowed_ipsscoped to the exact private IP/CIDR. OpenShell's SSRF protection blocks RFC1918/private upstreams by default even when the host and port match. - For plain HTTP services such as local Ollama on
:11434, prefer a narrow TCP passthrough endpoint withallowed_ipsinstead ofprotocol: restL7 rules unless the client is known to use HTTP CONNECT. If OpenShell logsendpoint has L7 rules; use CONNECT, the endpoint is using REST inspection with a non-CONNECT HTTP client. - Include the actual resolved executable path in
binaries, not only symlinks. For example,/usr/bin/python3may resolve to/usr/bin/python3.12. - If the executable is launched through a wrapper such as
bash, OpenShell may require the launcher path as well as the child binary. Check sandbox logs forbinary,ancestors, andreasonbefore widening policy. - Keep these policies least-privilege: exact host, exact port, exact
allowed_ips, and only the launcher/binary paths needed by that agent.
Typical local loop:
mix deps.get
mix format
mix testUseful CLI checks:
mn blueprint validate examples/research_flow
mn blueprint run examples/research_flow
mn inspect nodes
mn job monitorWhen Redis-backed tests or runtime flows are needed:
docker run -d --name mirror-neuron-redis -p 6379:6379 redis:7
mix testSome sandbox behavior also depends on OpenShell being available. If a test or manual check needs it and it is missing, say so clearly.
- Prefer small functions with clear pattern matching over deeply nested conditionals.
- Follow the current OTP style used in the touched module.
- Use supervision and message passing rather than ad hoc retry loops.
- Keep process state explicit and serializable when possible.
- Preserve current naming and alias/import style from nearby modules.
- Keep control-plane messages small and explicit.
- Preserve the separation between orchestration and isolated execution.
- Do not bypass manifest validation when adding manifest features.
- Do not sneak business-specific behavior into the runtime kernel.
- Prefer extending templates or config-driven behavior over branching the core runtime.
- Backward compatibility matters.
- Normalize inputs before validating where appropriate.
- Reject malformed manifests early with helpful errors.
- If manifest semantics change, update examples and relevant docs.
- Default output should remain readable for humans.
- Machine-readable output should stay stable if exposed publicly.
- Error messages should be direct and actionable.
- Add or update tests for every meaningful behavior change.
- Prefer the narrowest tests that cover the change.
- Update unit tests first, then run broader verification as needed.
- If you change CLI behavior, add or adjust CLI-facing tests.
- If you change manifest validation, add both happy-path and failure-path coverage.
- If you change recovery or lifecycle behavior, verify the event/status transitions.
At minimum, after code changes run:
mix format
mix testIf the change affects the executable or command surface, also run:
If you add or change a user-visible feature, update the relevant docs:
README.mdfor top-level usage changesdocs/cli.mdfor command behaviordocs/api.mdfor public inspection/control API changesdocs/development.mdfor contributor workflow changesexamples/when examples should demonstrate the new behavior
Aim for this sequence:
- Read the relevant module, adjacent modules, and tests.
- Make the smallest idiomatic change that satisfies the request.
- Add or update tests near the changed behavior.
- Run formatting and tests.
- Update docs only where behavior or operator expectations changed.
- broad refactors unrelated to the task
- new dependencies without strong justification
- business-specific agent types in the core runtime
- bypassing persistence or event publication in lifecycle changes
- changing public CLI semantics silently
- speculative abstractions that are not yet needed
README.mddocs/development.mddocs/runtime-architecture.mddocs/reliability.mddocs/cli.mddocs/api.md