Minimal self-evolving agent scheduler with hard core/evolution isolation
Project description
marrow-core
Minimal self-evolving agent scheduler with hard isolation between the immutable core and the writable agent workspace.
Migration note: profile-coupled assets have been removed from
marrow-core. New setups should provide prompts, context, role definitions, and runtime config from external profile/runtime repos such asmarrow-bot.
Prompt model
Use one mental model everywhere:
rules-> stable global policy in the external profile bundleroles-> canonical role identity and delegation boundaries in the external profile bundlecontext.d-> dynamic queue, state, and environment facts from the external profile bundleskills-> reusable procedures outside repo prompt assembly
Repo-root agents/ is retired. Do not add prompt material there.
Profile ownership
Role trees, prompt policy, and model maps are external profile concerns.
marrow-core no longer ships canonical roles/ or an in-repo casting flow. Use an external profile such as marrow-bot and cast it with uvx role-forge.
Canonical model
The canonical source of truth is:
- external profile
roles/for role prompts and layout - external profile
roles.tomlfor model-tier casting marrow_core/contracts.pyfor runtime inventory and workspace topologymarrow_core/work_items.pyfor cross-repo work-item contracts and storagemarrow_core/plugin_host.pyfor hosted plugin/background-service rendering.opencode/agents/as the generated runtime surface
Recommended installation path
Use marrow-core as runtime package only:
- install
marrow-coreviauvx/package tooling - provide runtime config outside core (or from an external profile repo)
- provide prompt/context/roles from an external profile root via
[profile] - use
uvx marrow-core validate --config /path/to/runtime-config.toml - use
uvx marrow-core install-service --config /path/to/runtime-config.toml
marrow-core no longer carries in-repo profile assets. New deployments should supply them externally.
uvx-first usage
Preferred invocation is package/runtime-first rather than source-checkout-first:
uvx marrow-core validate --config /path/to/runtime-config.toml
uvx marrow-core run --config /path/to/runtime-config.toml
uvx marrow-core install-service --config /path/to/runtime-config.toml --platform auto --output-dir ./service-out
The core runtime prompt is now intentionally generic. Execution policy belongs in external profile repos, not in marrow_core.heartbeat.
CLI
marrow run # root supervisor or single-user heartbeat loop
marrow run-once # one tick per scheduled agent, then exit
marrow dry-run # assemble prompts without running agents
marrow sync-once # one bounded sync attempt with structured result codes
marrow setup # init root runtime or single-user workspace
marrow scaffold # create a new writable workspace skeleton and starter config
marrow validate # check config and show summary
marrow doctor # verify workspace, context dirs, and agent command availability
marrow status # query live heartbeat state over IPC
marrow wake # wake one configured agent immediately via IPC
marrow install-service # render launchd or systemd service files
marrow task add # submit a task into tasks/queue via IPC
marrow task list # inspect queued tasks via IPC
Configuration
[service]
mode = "supervisor"
runtime_root = "/var/lib/marrow"
[profile]
root_dir = "/path/to/marrow-bot"
[ipc]
enabled = true
[self_check]
enabled = true
interval_seconds = 900
wake_agent = "orchestrator"
[sync]
enabled = true
interval_seconds = 3600
failure_backoff_seconds = 300
[[agents]]
user = "marrow"
name = "orchestrator"
heartbeat_interval = 10800
heartbeat_timeout = 7200
workspace = "/Users/marrow"
agent_command = "/Users/marrow/.opencode/bin/opencode run --agent orchestrator"
context_dirs = ["/Users/marrow/context.d"]
Runtime contract
marrow-core does not cast profiles itself.
The effective execution path is:
- maintain role definitions in an external profile repo
- cast them with
uvx role-forge cast --config <profile>/roles.toml - run
uvx marrow-core ...against a runtime config that points at that profile
Runtime boundaries
marrow_core/contracts.py- canonical role inventory and workspace topologymarrow_core/work_items.py- contract-first work-item models and filesystem storemarrow_core/plugin_host.py- plugin/background-service host manifests and unitsmarrow_core/prompting.py- context execution and prompt assemblymarrow_core/runtime.py- socket, queue, service-runtime, and binary path resolutionmarrow_core/task_queue.py- filesystem queue helpersmarrow_core/health.py- reusable doctor and self-check health checksmarrow_core/services.py- launchd/systemd renderingmarrow_core/scaffold.py- workspace scaffold and starter config generationmarrow_core/heartbeat.py,marrow_core/cli.py,marrow_core/ipc.py- orchestration layers
Workspace layout
/Users/marrow/
├── .opencode/agents/
├── context.d/
├── plugins/
├── work-items/
├── tasks/
│ ├── queue/
│ ├── delegated/
│ └── done/
├── runtime/
│ ├── state/
│ ├── checkpoints/
│ ├── logs/exec/
│ ├── logs/plugins/
│ └── plugins/
└── docs/
Work items and hosted plugins
marrow-core now carries two minimal cross-repo contracts:
- Work items: a stable JSON-backed model in
marrow_core.work_itemsfor gateways to ingest, bots to process, and dashboards to inspect. - Hosted plugins: a small
[[plugins]]config surface for dashboard/background-service processes.marrow_core.plugin_hostresolves runtime directories, emits a manifest, and can render autostart units for background services.
Typical hosted plugin/service examples include operator-side repos such as marrow-dashboard and marrow-task.
When marrow install-service is run with [[plugins]] configured, it now:
- writes a plugin manifest to
<primary-workspace>/runtime/plugins/manifest.json - renders autostart service units for
background_serviceplugins withauto_start = true
Minimal [[plugins]] shape:
[[plugins]]
name = "dashboard"
kind = "dashboard"
command = "python"
args = ["-m", "marrow_dashboard", "serve", "--config", "/etc/marrow/dashboard.toml"]
cwd = "/opt/marrow-dashboard"
workspace = "/Users/marrow"
config_path = "/etc/marrow/dashboard.toml"
capabilities = ["read_work_items"]
[[plugins]]
name = "gateway"
kind = "background_service"
command = "python"
args = ["-m", "marrow_gateway", "serve"]
cwd = "/opt/marrow-gateway"
workspace = "/Users/marrow"
auto_start = true
[plugins.env]
MARROW_WORKSPACE = "/Users/marrow"
See examples/runtime-config.example.toml for a copyable example and docs/contracts/work-items-and-plugins.md for the contract-first boundary.
Testing guidance
- prefer one high-signal behavior test over multiple helper tests for the same failure mode
- keep supervisor boundary coverage concentrated in
tests/test_supervisor.py - add lower-level tests only when a helper has meaningful branching not already covered by a higher-level test
Quick start
Fresh install:
uvx marrow-core validate --config /path/to/runtime-config.toml
Manual update attempt:
uvx marrow-core sync-once --config /path/to/runtime-config.toml
Note: sync-once is maintenance-only and still assumes a source checkout core_dir. For pure uvx runtime installs, prefer disabling sync or using an external repo-maintenance flow.
Expected sync outcomes:
0->noop10->reloaded11->restart_required1->failed
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file marrow_core-0.1.0.tar.gz.
File metadata
- Download URL: marrow_core-0.1.0.tar.gz
- Upload date:
- Size: 76.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8149c33fae71c87d70ea250c9b48bc6c7d9e85d919e6840235aad1f9211ad3bd
|
|
| MD5 |
a42598539d5d9d9eb0c26e112931c194
|
|
| BLAKE2b-256 |
b247c9b7a5e8e2b64ec7bb9c1e1e94c56d5198e4300431dec2bcaca60ce00669
|
File details
Details for the file marrow_core-0.1.0-py3-none-any.whl.
File metadata
- Download URL: marrow_core-0.1.0-py3-none-any.whl
- Upload date:
- Size: 41.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
09b719f32789432c75261881b3182ceb7dc814a1acded8776a8b5a9e8d6dc4b3
|
|
| MD5 |
95c0daea893ab649957be5b819c2b4f9
|
|
| BLAKE2b-256 |
f7f30967caf857500793c41b6fd767ea16ce2a52cb390b26707968966269b72d
|