culture-rules
Rules engine for the AgentCulture mesh: rules → conditions → workflows →
actions, carried out by actors (agents, humans, code, services,
robots, …). It is a Python library, culture_rules, with a CLI, an HTTP
API, an MCP server and a graph-first React Flow editor that has four tabs:
Rules | Workflows | Actors | Statistics.
Who it is for. Two readers, one system:
- The operator composing and supervising automation across spark, thor and spark2 from a browser at rules.culture.dev.
- Mesh agents that drive the same rules, workflows and actors through
the
culture-rulesCLI and MCP server.
Why. One graphical, agent-operable place to decide when work happens, how it flows across machines and who does it, and it keeps working when one machine falters, so automation stops being per-host glue only its author understands.
The model
A rule says when work happens, and reads as a small flow:
PR approved → base = main → Review PR → Comment
trigger condition workflow action
| Concept | What it is |
|---|---|
| Rule | A trigger, an optional condition, an optional workflow and a required action. A rule can follow another rule (must run after / may run after), supersede another, and consume the outputs its predecessor explicitly exports. It is placed on a machine, an actor or a capability requirement, which decides where its trigger and condition evaluate. |
| Condition | A typed JSON predicate over the trigger and context, evaluated deterministically (never eval()). It is edited graphically; a CEL-style text form is the advanced view. |
| Workflow | Reusable how: typed inputs, internal variables, steps (logic, AI call, code run, actor task, loops), and explicit outputs. Each step has typed ports and its own placement, so one run can hop machines. A workflow doesn't know what triggered it. |
| Action | The terminal side effect of a rule: post a comment, send a message, call a service, ask a human. |
| Actor | Who/what does the work: agent, human, service, daemon, runner, robot. Actors carry capabilities, limits (budgets, concurrency) and secret references. They are not a stage in the rule chain. |
| Machine | An explicitly enrolled host (spark, thor, spark2): address, platform, capabilities such as gpu, and roles (store member, engine node, runner). |
| Run | One execution of a rule. Its state is persisted in MongoDB, so human steps and engine restarts are safe, and each step records its host and outcome. |
The editor
The editor has four primary tabs: Rules | Workflows | Actors | Statistics. Runs, history, ledger and inbox are not tabs; they appear in context, inside a rule or workflow.
- Rules is a rule list plus the focused rule as a vertical flow.
Rules start from "New rule", which asks "When does this happen?", and grow through a
+. - Workflows is the free-form React Flow canvas with typed ports and the machine shown on each node. A run lights up its path on the graph.
- Actors is a large-type roster that expands inline.
- Statistics has one lane per enrolled machine: online state, CPU, GPU and memory load, what it is running, queue depth and 24h ok/failed.
The design canvas (https://claude.ai/artifact/Jgm3JPnAhKWpeiCxFXvNBi, row "Chosen") is the visual source of truth. The goal is visual composition, not an admin dashboard:
- large type and large targets;
- minimal chrome and prose;
- smooth transitions;
- keyboard- and reduced-motion-accessible;
- raw YAML/JSON as an advanced mode only.
The editor lives in web/. The wheel ships the built
bundle as culture_rules/web_dist, which the API serves same-origin, so
running it needs no Node.
Install
The core library and CLI have no third-party dependencies. Everything else is an optional extra:
| Extra | Adds | For |
|---|---|---|
culture-rules[server] |
FastAPI, uvicorn | culture-rules serve (the HTTP API and editor) |
culture-rules[store] |
pymongo | the MongoDB store (the API and node run need it) |
culture-rules[mcp] |
mcp |
culture-rules mcp |
culture-rules[events] |
events-cli |
the durable events-cli trigger subscription |
culture-rules[yaml] |
PyYAML | YAML export/import and repo-based agent actors |
culture-rules[backup] |
boto3 | S3 backup and restore |
culture-rules[agent] |
agentirc-cli |
agent actors reached over the mesh |
pip install 'culture-rules[server,store,mcp,events,yaml]'
Quickstart
Full, executed walkthrough: docs/demo.md. In short:
# 1. a MongoDB replica set (TLS + auth) and the env vars; see docs/operations/replica-set.md
export CULTURE_RULES_MONGO_URI=... CULTURE_RULES_MONGO_TLS_CA_FILE=...
# 2. the API and editor (one per serving host)
culture-rules serve --port 8791
# 3. the engine node (one per host that runs steps)
culture-rules node run --host spark # add --once for a single cycle
# optional: CULTURE_RULES_REPORT_CHANNEL=#ops posts each finished run's summary to that
# mesh channel (via `culture channel message`; logged instead when culture is not on PATH)
# 4. drive it from the CLI (writes preview until --apply)
export CULTURE_RULES_API_URL=http://127.0.0.1:8791
culture-rules machines create --apply --body '{"name":"spark","roles":["engine_node","runner"]}'
culture-rules rules list
# 5. the web editor: open the API's address in a browser
From a checkout, uv sync installs everything above, and
uv run culture-rules whoami, uv run pytest -n auto and
uv run teken cli doctor . --strict work as in CI.
CLI
| Verb | What it does |
|---|---|
rules, workflows, actors, machines |
list, show, create, update, enable, disable, delete, restore, purge; rules, workflows and actors also export / import; machines also drain / undrain; rules also run and replay. |
runs |
list, show, cancel, pause, resume, controls. |
serve |
Run the HTTP API (needs the server extra). |
node run |
Run this host's engine node (--once for one cycle). |
mcp |
Serve the same verbs as MCP tools over stdio (needs the mcp extra). |
whoami, learn, explain <path>, overview, doctor, cli overview |
Identity and self-description for agents. |
Every command supports --json. Results go to stdout, and errors and
diagnostics go to stderr; the two are never mixed. Exit codes: 0
success, 1 user error, 2 environment error, 3+ reserved. Writes are
dry-run by default, and --apply commits them. Deletes are soft
(restorable); purge is admin-only. The CLI is a client of the HTTP API
(CULTURE_RULES_API_URL, with CULTURE_RULES_TOKEN for a service token),
except node run, which is the engine and talks to the store directly.
MCP
culture-rules mcp exposes the same verbs as MCP tools, with the same
dry-run default, so an agent can do anything the operator can do from the
CLI. A parity test keeps the two surfaces identical.
{ "mcpServers": { "culture-rules": { "command": "culture-rules", "args": ["mcp"],
"env": { "CULTURE_RULES_API_URL": "http://127.0.0.1:8791" } } } }
Architecture
browser (Rules | Workflows | Actors | Statistics) mesh agents
│ Cloudflare Access SSO CLI / MCP (stdio)
▼ │
cloudflared ──► loopback listener ┐ ▼
├─► HTTP API ◄── service-token (LAN) listener
api/openapi.json (the one contract; web/src/api/types.ts is checked against it)
│
▼
MongoDB replica set (rules, workflows, actors, machines, runs, events)
▲
engine node on each host ─────────┘ heartbeat, ingest (events-cli), evaluate
(spark primary; thor, spark2 redundant) placed rules, drive steps, report
culture_rulesis the library: model, engine, actors, events, machines, store, io. The CLI, API, MCP server and node are thin layers over it.- The API contract is pinned in
api/openapi.json, and CI diffs the served schema against it. The JSON Schemas for the model are inschemas/. - Multi-host safety: each firing and step is claimed by exactly one host, so redundancy never double-executes an action.
- Secrets are references (
grant:<NAME>), never values in a definition, export or log.
Operations
docs/operations/replica-set.md: the MongoDB replica set across hosts (TLS, auth, the orin third voter).docs/operations/backup.md: S3 backup, schedule and the restore drill.docs/operations/rules-culture-dev.md: the rules.culture.dev tunnel, Cloudflare Access and the loopback listener.
Background
culture-rules is built to replace scattered per-host automation: YAML/CEL
declarations on thor, cron jobs and ad-hoc scripts per host, and agents
nudged by hand over IRC. The spec
(docs/specs/2026-10-03-culture-rules-engine-editor.md)
records what was found and cites its scope entries:
- s7, s8, s9: culture-nodes is a durable workflow orchestrator whose declarations are trigger-condition-action rules with a CEL condition. It is the closest precedent. culture-rules stays a separate engine, with no runtime dependency on it.
- s10, s11: its Postgres actors table and provider-neutral actor protocol are the precedent for a DB-based actor registry.
- s12, s13, s14: the mesh knows spark, thor and orin but not spark2, and liveness is not enrolment, so machines are explicit enrolled records.
- s15:
AgentClientis the semver-tracked way to reach agent actors over the mesh. - s25: cultureflare documents no origin-side validation of Access tokens, so validating them is this repo's job.
The product model and UX come from issues #1 (the build brief) and #2 (the product model), and the four-tab decision is recorded in the spec.
Prompt files by harness
Four harnesses read four root files, with no shared base. Each file is
read by exactly one harness, and there is intentionally no AGENTS.md:
| Harness | File(s) |
|---|---|
| Claude Code | CLAUDE.md (the mesh-resident prompt, and the fullest write-up) |
| Pi / associate | AGENTS.override.md + .pi/SYSTEM.md |
| colleague | AGENTS.colleague.md |
| Qwen Code | QWEN.md |
There are two separate selections over this clone:
- The interactive harness: whichever binary you run. All four are live at once.
- The mesh resident: the
backendthatculture.yamldeclares, hereclaude.
See docs/harness-selection.md and
docs/automation-contract.md.
Skills
.claude/skills/ vendors 19 skills (cite-don't-import), including the
devague workflow (scope → think → spec-to-plan →
assign-to-workforce), which drives the build. See
docs/skill-sources.md for provenance and the
re-sync procedure.
Contributing
See CLAUDE.md for the conventions:
- every PR bumps the version;
- PRs go through the
cicdlane; - worktree layout and memory discipline.
License
Apache 2.0 — see LICENSE.
Metadata
Release files for culture-rules 0.11.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| culture_rules-0.11.3.tar.gz | 3.9 MB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| culture_rules-0.11.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 4.3 MB
Release files / culture_rules-0.11.3.tar.gz
| Download URL | culture_rules-0.11.3.tar.gz |
|---|---|
| Size | 3.9 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
33462412b300480f5a1ab1abe3ace9eb0eb3a7c37f2e6e013a6a4face746e805
|
|
BLAKE2b-256 checksum How to use checksums |
e6cd9c3a13655b248ee766f0c8153a750f90367088f8993e080e69735b370be8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / culture_rules-0.11.3-py3-none-any.whl
| Download URL | culture_rules-0.11.3-py3-none-any.whl |
|---|---|
| Size | 360.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
bfb710dd7ba5938a6c286af0c7c244226efbc1d0a33142c1b12a6cc25b879e54
|
|
BLAKE2b-256 checksum How to use checksums |
f65eff95a5c250aac1b87c7d41edb6ca1f6ed9e701fa6953453159a49a3499ab
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for culture-rules 0.11.3
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.