ReferenceFormats and configPolicy YAML

Policy YAML

yaml
version: 1
project: acme-checkout
policies:
  - name: production-database-protection
    match:
      actions: ["database.delete", "database.drop"]
      environments: ["production"]
    decision:
      effect: block
      reason: No AI-initiated destructive database operations in production.

Top level

versionnumber

1

projectstring

The governance scope. Declared, never inferred

policieslist

The rules

Two repositories that declare the same project share one policy and memory scope. See Orgs, workspaces, projects.

A policy

namestring

Unique. Appears in every audit event that matched

descriptionstring

Optional, for whoever reads the file

matchobject

What this rule applies to

decisionobject

What happens when it does

match

Every field takes wildcard patterns (*), and an omitted field matches everything. That default is the most common source of a rule that fires more widely than intended.

Field

actions

The action verb, file.write, deploy.service, mcp.*

targets

The path, resource or service named

environments

production, staging, whatever you declared

branches

The git branch the work sits on

workingDirectories

Where the call was made

agents

Which agent is asking

arguments

The call's own arguments, by name

windows

When the rule applies

arguments

yaml
    match:
      actions: ["shell.execute"]
      arguments:
        command: ["*rm -rf*"]

Every named argument must match. An argument the call does not carry matches only the bare "*".

Evaluated in-process by @memnox/local-gate, inside the MCP firewall or the editor hook, so raw payloads never leave the machine.

windows

yaml
      windows:
        - { days: [1,2,3,4,5], startHour: 17, endHour: 9 }
        - { days: [0,6], startHour: 0, endHour: 24 }

days runs 0 to 6, where 0 is Sunday. Hours are on a 24-hour clock, and a startHour greater than endHour wraps past midnight, so 17 to 9 means "overnight". Several windows are OR-ed: the rule applies if the moment falls in any of them.

The instant is passed into evaluation rather than read from a clock inside the engine, so replay reproduces the same verdict.

decision

effectenum

allow · block · require_approval · redact

reasonstring

What a human reads at the moment they are blocked

approverslist

Required for require_approval

minApprovalsnumber

Quorum. Default 1

modeenum

monitor records the verdict without applying it

rateLimitobject

{ max, windowSeconds }

Precedence

When several policies match, the most restrictive effect wins:

block  >  require_approval  >  redact  >  allow

Order in the file does not matter. There is no "first match wins", because a rule set whose meaning depends on line order is one that breaks when somebody sorts it.

effect: redact

Masks secrets in the arguments and forwards the call. Needs an enforcement point that can rewrite the payload, the MCP firewall can; an editor hook blocks instead. Masked text is re-scanned, and a surviving finding blocks.

mode: monitor

yaml
    decision:
      effect: block
      mode: monitor

The action proceeds and the audit event records the verdict it withheld. This is how one rule is rolled out while the rest of the file enforces.

rateLimit

yaml
    decision:
      effect: allow
      rateLimit: { max: 10, windowSeconds: 3600 }

Counted per agent and per rule by the runtime. Only an action that actually proceeds spends a slot, and the local gate never counts, this needs a running runtime.

Quorum

yaml
    decision:
      effect: require_approval
      approvers: ["eng-lead", "security"]
      minApprovals: 2

Grants accumulate until the quorum is met. One person counts once, and a single denial ends it.

Validating and simulating

bash
memnox validate [file]
memnox policy simulate -f candidate.yaml
memnox policy version

simulate replays your real recorded history and warns loudly wherever an action becomes more permissive.

A fuller example

yaml
version: 1
project: acme-checkout
policies:
  - name: no-recursive-delete-in-payments
    match:
      actions: ["shell.execute", "mcp.run_shell"]
      arguments: { command: ["*rm -rf*"] }
      workingDirectories: ["/srv/payments*"]
    decision:
      effect: block
      reason: Recursive delete is not an agent action here, ask #platform.
 
  - name: release-branches-need-a-human
    match:
      actions: ["shell.execute"]
      arguments: { command: ["*git push*--force*"] }
      branches: ["main", "release/*"]
    decision:
      effect: require_approval
      approvers: ["eng-lead"]
      reason: A force-push can destroy work that exists nowhere else.
 
  - name: deploy-budget
    match:
      actions: ["deploy.*"]
      environments: ["production"]
    decision:
      effect: allow
      rateLimit: { max: 10, windowSeconds: 3600 }