Skip to main content
A rule names an action, optional conditions on it (where), what to do (verdict), and what to tell the agent (say).

Conditions

Each where value is matched against one field:
  • "main|master" — any of the alternatives.
  • "*/migrations/*" — * matches any run of characters, including /; ? matches one character.
  • "!main|dev" — a leading ! negates the whole value: anything except main or dev.
  • A field the action doesn’t have never matches, so the rule doesn’t fire.

Actions

Commands are parsed, not pattern-matched. cd, git -C, bash -c, eval, env and sudo wrappers are followed. Writes through >, tee, cp, mv and sed -i count as file writes. Inside a git repository, every action also has repo (owner/name, from the origin remote) and current_branch. File and directory actions have dir.
Test a rule before you save it. synheart guard check <command> prints the action and its fields, and which rule would fire.

Where rules come from

Rules load in this order. When two have the same id, the first one wins.
  1. Built-in rules. An agent can’t grant exceptions, edit rule files or turn the guard off. These can’t be overridden.
  2. Team rules, set by an admin under Agents → Team rules and synced to each machine.
  3. Your own rules, in ~/.synheart/guard/rules.yaml (synheart guard init writes a starter set).
  4. Exceptions you granted with synheart guard allow.
  5. Repository rules, in .synheart/guard.yaml at the repository root.
So a personal or repository file can add rules, but can’t redefine a team rule.

A team example

When rules are too strict

Agents → Team lists rules people always let through when asked. Those are candidates to relax, so developers are asked less. Before turning a new rule on for everyone, add shadow: true and watch the would fire column for a week.