{
"slug": "rotting-bugs",
"filter": {
"op": "AND",
"nodes": [
{ "field": "type", "eq": "bug" },
{ "field": "stale_days", "gte": 3 },
{ "field": "children_all_done", "eq": true }
]
}
} Autonomous systems
need a spine.
ConvOps is the workflow engine that gives them one. Describe the loop once, from the AI client you already use. Your agents run it, step by step, run after run, gated where you demand it. You own the execution layer. ConvOps owns the governance.
an mcp server · one line of config · nothing to migrate
scroll. this page is a workflow._
The whole install is one line.
ConvOps is an MCP server. Paste it into Claude Code, Cursor, ChatGPT, or any MCP client. On first use it opens a browser to sign in. No keys, no config files, nothing to migrate.
https://mcp.convops.app/_
claude mcp add --transport http convops https://mcp.convops.app/- describe. Say the process. That is the interface. You define a workflow from the AI client you already use (Claude, ChatGPT, your own agent). Describe how the work should go, in plain language. ConvOps compiles it into structure: steps, gates, decisions, branches.
- route. Every task gets the right workflow. Automatically. You defined the process once. From now on, each new task is matched to the workflow that owns it (bugs to bug-fix) by type, vertical, tags, project, or plain language. Nobody wires anything per task, ever.
- trigger. You create a task. That is your whole job. Type "payment webhook returns 500", or let your stack or a schedule create it. The workflow attaches itself, your agent receives step one, and execution begins. You wrote no prompt and assigned nothing.
- memory. Give the run a memory. Exactly where you choose. ConvOps ships the brain as tools, not magic. Write "recall first" into a step and the agent gets memories (what past runs learned) and routes (where the code lives) in one query, no re-exploring. Task notes hand run-local state to whoever executes the next step. Nothing is stored without you.
- step. A step is not a prompt. The workflow hands over one instruction at the moment the work reaches it. No forty page brief. No system prompt that quietly goes stale. The model only ever sees what is next.
- decision. One step. Three exits. A decision step reads the state of the work and picks a path automatically, against real task fields. One branch invokes an entire sub-workflow with its own steps, gates and branches, runs it to the end, and merges back with everything it learned.
- parallel. Three agents. Same instant. A parallel group runs steps concurrently (the fix, the tests, the docs), each lane with its own agent, on its own runner if you want. Claude on one, your self-hosted model on another. The group merges before the run moves on.
- executor. Your machines. Your clients. Your rules. ConvOps never runs your code. It governs whoever does. Agents execute on the tooling you already have: Claude Code or Kimi Code at your desk, OpenCode as a built-in backend, ConvOps cloud when you want it hosted, or a custom runner you register on your own infra.
- gate. It does not ship until you say so. A gate is structural. It lives in the workflow, not in wording a model can talk its way around. This one waits twice: for the parallel work to land, and for you. The run stops. You decide. Only then does the line continue.
- policy. Change the rule, not the rails. Policies are governance rules assigned to workflows, one by one or globally, and injected into whichever step is active right now. Edit one and every run in flight picks it up on its next step. No template surgery. No redeploy.
- dispatch. Nobody starts it. That is the point. Give the workflow a schedule and it stops waiting for you. Every fire creates a task that carries the whole process: recall, run, branch, gate, close. You govern it at the gates. It does the rest.
Say the process. That is the interface.
You define a workflow from the AI client you already use (Claude, ChatGPT, your own agent). Describe how the work should go, in plain language. ConvOps compiles it into structure: steps, gates, decisions, branches.
{
"id": "bug-fix",
"steps": 7, "gates": 1,
"decisions": 1, "parallel": 1
}✓ compiled. Every future bug now follows it.
Every task gets the right workflow. Automatically.
You defined the process once. From now on, each new task is matched to the workflow that owns it (bugs to bug-fix) by type, vertical, tags, project, or plain language. Nobody wires anything per task, ever.
{
"applies_to": [{
"type": "bug",
"vertical": "development",
"default": true
}],
"classification_examples": [
"Checkout crashes on Safari",
"Payment webhook returns 500"
]
}You create a task. That is your whole job.
Type "payment webhook returns 500", or let your stack or a schedule create it. The workflow attaches itself, your agent receives step one, and execution begins. You wrote no prompt and assigned nothing.
{
"id": "a91f24c8",
"title": "Payment webhook returns 500",
"type": "bug",
"workflow": "bug-fix",
"step": "1 of 7"
}Give the run a memory. Exactly where you choose.
ConvOps ships the brain as tools, not magic. Write "recall first" into a step and the agent gets memories (what past runs learned) and routes (where the code lives) in one query, no re-exploring. Task notes hand run-local state to whoever executes the next step. Nothing is stored without you.
- context_query: memories, routes and related tasks in one call
- task_notes: DECISION, BLOCKER, CONTEXT. The baton the next step reads
- context= on any workflow_advance stores a note. require_context gates demand one
- auto-capture: three org toggles (progress, decisions, corrections), off by default
{
"context_query": "payment webhook 500",
"returns": {
"memories": ["X-Sig header moved in v2"],
"routes": ["api/payments/webhook.py"]
},
"org_settings": {
"brain.auto_memory_progress": true,
"brain.auto_memory_decisions": false
}
}A step is not a prompt.
The workflow hands over one instruction at the moment the work reaches it. No forty page brief. No system prompt that quietly goes stale. The model only ever sees what is next.
- Instructions arrive in context, never up front
- Your rules live here: "notify me", "wait for my reply", "never touch prod"
- Edit a step once and every future run inherits it
{
"id": "failing-test",
"name": "Failing Test",
"agent": "implementer",
"status": "in_progress",
"instructions": "Write the test that
reproduces the crash. Red first.
Notify me when it goes green."
}One step. Three exits.
A decision step reads the state of the work and picks a path automatically, against real task fields. One branch invokes an entire sub-workflow with its own steps, gates and branches, runs it to the end, and merges back with everything it learned.
{
"decision": true,
"conditions": [
{ "id": "simple",
"when": { "task_field": "complexity",
"equals": "S" } },
{ "id": "unclear",
"invoke": "deep-research" },
{ "id": "go", "when": "default" }
]
}Three agents. Same instant.
A parallel group runs steps concurrently (the fix, the tests, the docs), each lane with its own agent, on its own runner if you want. Claude on one, your self-hosted model on another. The group merges before the run moves on.
{
"parallel": [
{ "id": "fix", "agent": "implementer" },
{ "id": "tests", "agent": "test-writer",
"executor": "your-runner" },
{ "id": "docs", "agent": "docs-writer" }
]
}Your machines. Your clients. Your rules.
ConvOps never runs your code. It governs whoever does. Agents execute on the tooling you already have: Claude Code or Kimi Code at your desk, OpenCode as a built-in backend, ConvOps cloud when you want it hosted, or a custom runner you register on your own infra.
{
"executors": [
{ "slug": "local", "is_system": true,
"description": "claude code · kimi code" },
{ "slug": "opencode", "is_system": true },
{ "slug": "conveyor", "is_system": true,
"description": "convops cloud" },
{ "slug": "gpu-box", "runner": "custom",
"description": "your infra" }
],
"precedence": "step > task > org default"
}It does not ship until you say so.
A gate is structural. It lives in the workflow, not in wording a model can talk its way around. This one waits twice: for the parallel work to land, and for you. The run stops. You decide. Only then does the line continue.
- requires_approval: a human has to say go
- wait_for_children: child work has to land first
- task_status, sequential_children: twelve keys in all
{
"id": "approve",
"gate": {
"requires_approval": true,
"wait_for_children": true,
"prompt": "Ship it?"
}
}Change the rule, not the rails.
Policies are governance rules assigned to workflows, one by one or globally, and injected into whichever step is active right now. Edit one and every run in flight picks it up on its next step. No template surgery. No redeploy.
{
"slug": "cite-or-cut",
"text": "Every factual claim carries a
source or it does not ship.",
"enabled": true,
"assigned": ["bug-fix", "content-os"]
}Nobody starts it. That is the point.
Give the workflow a schedule and it stops waiting for you. Every fire creates a task that carries the whole process: recall, run, branch, gate, close. You govern it at the gates. It does the rest.
- scheduled: RRULE cadence, deadlines
- triggered: an event in your stack fires it
- sdk: your application starts the run
{
"rrule": "FREQ=WEEKLY;BYDAY=MO;BYHOUR=9",
"creates": "task -> workflow: bug-sweep",
"supervision": "gates only"
}Real processes already run on this.
Not mockups. These are the shapes of workflows in production today. Content pipelines that publish daily without a human. Delivery plans that gate on sign-off. Bug flows that branch on reality. Pick one and watch it run.
A publishing pipeline that fires itself every morning and never fakes a green.
- 01
Fires itself
An RRULE schedule creates the day’s task. Nobody starts it.
- 02
Recalls before acting
Queries memory first: yesterday’s context, learned rules.
- 03
Researches and drafts
Agents source, check and write, one governed step at a time.
- 04
Hard verification gate
Claims cited, entities verified. A red files a bug task. The loop never fakes green.
- 05
Publishes
Content ships with its provenance attached.
- 06
Sweeps and closes the loop
Verifies its own output landed. Tomorrow it all runs again.
The loop pulls its work. Nothing pushes it.
When a schedule fires, the agent does not get handed a to-do list. It asks a pool: a saved query resolved live on every call, never a cached list. pools_next answers with exactly one task, or with nothing, and an empty hand is an answer the workflow can branch on.
{
"id": "a91f24c8",
"title": "Payment webhook returns 500",
"type": "bug",
"stale_days": 4
}- stale_days, workflow_idle_days, children_all_done: computed fields that say what is rotting and what is stuck
- The grammar is typed and validated, never string-built. Validation is also the injection guard
- This is the difference from a cron runner: cron fires on time, a pool decides on state
Autonomy that leaves receipts.
Every mutation writes an audit row that keeps two identities apart: the agent is a label it declares about itself, the human is derived on the server from the verified credential and is never a parameter an agent could forge. Gates are evaluated by the engine; one that is not met does not move.
{
"actor": "implementer",
"actor_user_name": "David Marsa",
"action": "updated",
"entity_type": "task",
"changes": {
"status": { "old": "review", "new": "completed" }
}
}{
"current_step": "approve",
"unmet_conditions": [
"Requires explicit user approval"
]
}- Field level before and after diffs on tasks and workflow instances
- Every workspace sits behind Postgres row level security with FORCE: even the table owner cannot bypass it. No tenant context, no query
- Policies reach the agent inside the active step, at the moment it acts. Edit one and every run in flight picks it up
There is a system of record behind this.
The engine you scrolled is the same one the app renders. Workflows drawn from their stored definitions, a dashboard over the live task graph, agents scored by their recorded actions. These are captures, not mockups.



One workspace per system you automate.
Development, content, a client: each runs as its own workspace with its own workflows, executors, policies and memory. Recall searches across every workspace you belong to in one query. Ownership stays isolated. Search does not.
You just scrolled an autonomous loop.
One message defined it. Work routed itself into it. Then it ran: it recalled what past runs learned, branched three ways, invoked a sub workflow with its own gates, put three agents in parallel on clients you already run, waited for you at a gate, absorbed a policy mid run, and closed its own loop on a schedule. You wrote none of it as code.