Skip to content

Memory rules

Rules are if-this-then-that for project broadcasts. When an event of on_kind fires and the optional where predicate matches, one or more actions run server-side with template substitution from the event payload. No client glue, no polling.

Three actions are available: set_broadcast, pin_memory, and record_turn. Rule actions can’t install other rules; the recursion guard suppresses rule re-dispatch from inside an action so set_broadcastbroadcast_set → rule loops don’t run away.

list_default_rules returns three ready-to-install rules. The dashboard’s Rules page renders them with one-click install buttons, but the same data is available over MCP for agent-driven setup.

namefires ondoes
error-pinturn_recorded where metadata.kind == "error"Auto-pins a memory referencing the turn so errors survive consolidation.
claim-watchdogclaim_expiredSets the last_abandoned_claim broadcast so downstream agents can detect orphaned work.
review-routerturn_recorded where metadata.tag == "needs_review"Publishes a review_queue:latest broadcast carrying the actor + content preview.

Install one in two calls:

const { defaults } = await mt.listDefaultRules();
const errorPin = defaults.find((d) => d.name === "error-pin")!;
await mt.installRule(errorPin);

Install your own with install_rule. Example: pin every TS2345 compile error.

await mt.installRule({
name: "ts2345-watchdog",
description: "Pin every TS2345 'argument of type' error",
on_kind: "turn_recorded",
where: {
"payload.metadata.kind": "error",
"payload.content_preview": { "$matches": "TS2345" },
},
actions: [
{
tool: "pin_memory",
args: {
content: "TS2345 hit: ${payload.content_preview}",
tags: ["error", "ts2345"],
},
},
],
});

The where predicate is JSON-shaped, Mongo-flavored:

  • Plain values are $eq shorthand: { "payload.role": "tool" }
  • Operator forms: $eq, $ne, $in, $nin, $matches (regex), $exists, $gt, $gte, $lt, $lte
  • Multiple keys at any level AND together
  • Top-level $or flips to disjunction: { "$or": [{ "payload.role": "tool" }, { "payload.role": "system" }] }
  • Field paths use the same convention as action template substitution: payload.X / event.X

Bad predicates evaluate to false (rule doesn’t fire) rather than throwing. Typos can’t crash dispatch.

Rules can listen to: turn_recorded, memory_pinned, memory_forgotten, broadcast_set, consolidation_completed, claim_acquired, claim_released, claim_expired.

presence_updated is intentionally excluded; a rule action that emits a turn would trigger the next user heartbeat, which would run the rule again.