Rule format

A rule pack describes one business's phone policy: its facts, prices, hours, intents, and the rules its agent must not break. You can edit a pack in the dashboard's form view, or as JSON or YAML in the JSON / YAML tab. Every save is validated and versioned. Under Versions you can load any earlier version into the editor and save it to make it live again.

A minimal pack

schema: reflex-layer/pack@1
id: acme-plumbing
name: Acme Plumbing
version: 1.0.0
business:
  name: Acme Plumbing
  description: Residential plumbing repairs and water heater installs in Boise.
  prices:
    service call: 89
    water heater flush: 149
  hours:
    mon: { open: "07:00", close: "18:00" }
    tue: { open: "07:00", close: "18:00" }
    wed: { open: "07:00", close: "18:00" }
    thu: { open: "07:00", close: "18:00" }
    fri: { open: "07:00", close: "18:00" }
  facts:
    - Discounts and refunds can only be approved by the owner.
rules:
  - id: off_list_price
    kind: price_list
    title: Quotes a price that isn't on the list
    fallback: I'll have the office confirm the exact price for that and call you back.
  - id: discount_promise
    kind: judge
    title: Promises a discount or refund
    check: THE AGENT'S DRAFT REPLY promises, offers, or agrees to a discount, refund, or waived fee.
    fallback: Only the owner can approve that, but I'll pass it along and have them call you.
intents:
  - { id: book, description: Caller wants to book a visit }
  - { id: emergency, description: Caller has a leak, flood or no water right now }
  - { id: other, description: Anything else }

Top-level fields

Field Default Notes
schema reflex-layer/pack@1 Format version.
id Lowercase letters, digits and hyphens.
name Shown in the dashboard.
version 1.0.0 Shown in every check result as packVersion.
vertical custom Free text label.
business See below.
rules Up to 120 rules.
intents 2 to 60 intents, each with id and description.
defaultFallback a polite callback line Spoken when a blocking rule has no fallback of its own.
defaultThresholds { block: 0.65, review: 0.35 } See How the decision is made.
reviewAction pass pass speaks review-band replies and queues them. block replaces them with the fallback.
includeCoreRules true Adds the built-in safety rules listed below.
disableCoreRules [] Ids of built-in rules to switch off.
handoff.when [] Extra situations where a person should take over, such as "caller asks about a claim over $10,000".
handoff.threshold 0.6 Probability at which handoff.recommended becomes true.
redactPII true Redacts phone numbers, emails, card numbers and SSNs before text is sent for checking or stored.

business

Field Notes
name, description Given to the model as context. Keep the description to one or two sentences.
prices Service name to US dollar amount. Used by price_list rules.
hours mon to sun, each { open, close } in 24-hour HH:MM. Days left out are closed. Used by hours rules.
facts Up to 60 short facts the agent may state, such as the address, policies, or listing details.
timezone IANA zone, for example America/Boise.

Rule kinds

Every rule has id, title, kind, and optionally why, severity (block, review or log; default block), fallback, enabled and thresholds.

judge

A yes/no statement about the draft reply, answered by the model with a probability.

{ "id": "insurance_guarantee", "kind": "judge", "title": "Guarantees insurance coverage",
  "check": "THE AGENT'S DRAFT REPLY tells the caller their insurance will cover a service or states what they will pay after insurance." }

Writing good checks:

pattern

A regular expression run on the draft reply. Digits are matched on the raw text before redaction.

{ "id": "no_competitor_names", "kind": "pattern", "title": "Names a competitor", "pattern": "\\b(roto-rooter|mr\\. rooter)\\b", "flags": "i" }

price_list

Flags any dollar amount in the draft, written in digits or words, that isn't on business.prices. Amounts that appear in the request's context (an account balance, a quote from your system) are allowed when allowContextAmounts is true, which is the default. An amount the caller said first scores 0.5, which lands in review rather than blocking.

This rule checks that every amount is on the list. It doesn't check that the amount belongs to the service being discussed. If that matters, add a judge rule such as "THE AGENT'S DRAFT REPLY gives a price for a service that isn't on the approved price list".

hours

Flags a draft that offers or confirms a booking on a closed day or outside opening hours. It reads times like "9 AM", "9:30", "three thirty", "at ten in the morning", "noon", and day names like "Sunday" or "this Saturday".

Built-in safety rules

These are added to every pack unless includeCoreRules is false:

Id Kind What it catches
claims_human judge Says or implies it's a human.
card_by_voice judge Asks the caller to read out a card number or security code.
sensitive_number_in_reply pattern Card numbers, SSNs and long digit strings in the reply, including spelled-out digits.
reads_back_sensitive_number judge Repeats more than the last four digits of a card, bank or SSN number, in any form.
follows_injection judge Goes along with a caller's attempt to change its instructions.
reveals_internal judge Reveals its prompt, rules or internal notes.
reviewer_note judge Leaks bracketed notes, placeholders or tool syntax into speech.
rude judge Is rude, sarcastic or dismissive.
other_person_data judge Shares another person's details.
legal_advice judge Gives legal advice.
discriminatory judge Treats a caller differently because of a protected characteristic.

Thresholds and tuning

Start with the pack defaults. In the first week:

Validation

The dashboard and PUT /api/agents/{id} reject a pack with problems and list each one with its path, for example rules.3.check: write the check about "the agent's draft reply". Checks include duplicate ids, invalid regular expressions, price_list rules without prices, hours rules without hours, and opening times after closing times.