The rules’ test cases, with the latest result of each.
The cases the policy engine, guardrails and test calls are checked against, and their results. The rules themselves are on the rules page.
Last run · November 2, 2026
50 of 50
cases passed
169 expectations across 9 areas.
The policy engine
Every proposal that moves money goes through it. It answers allowed, needs you or stopped.
| The case | Expected | Result |
|---|---|---|
A $100 to $110 daily budget, inside every limit, set to You approveevaluateAction › queues for approval at the default autonomy level | Needs you: waits in your inbox | ✓ Passed1 check |
The same change, with budget changes set to Acts and notifies youevaluateAction › approves when autonomy allows it | Allowed: goes ahead, and you’re told | ✓ Passed1 check |
Any change while the stop button is on, even with every action set to act aloneevaluateAction › rejects when the stop button is on, regardless of autonomy | Stopped | ✓ Passed1 check |
$100 to $150 a day, a 50% change, against the 20% limit per changeevaluateAction › rejects changes larger than the per-action limit | Stopped | ✓ Passed1 check |
An agent’s total daily budget raised, or cut, by more than the 20% limit in one changeevaluateAction › measures the limit per change on the agent's total daily budget, up and down | Stopped, either way | ✓ Passed5 checks |
Money moved between an agent’s campaigns at the same total, under the reallocation limitevaluateAction › lets a reallocation under the limit go ahead at the permission level | Goes ahead at the agent’s permission level | ✓ Passed2 checks |
The same move over the reallocation limit, with budget changes set to Acts and notifies youevaluateAction › asks a person for a reallocation over the limit, whatever the permission level | Needs you: waits in your inbox | ✓ Passed3 checks |
Launches of $40 and $60 a day, with $200 a day already running and a $250 daily capevaluateAction › allows new spend from zero but enforces the daily cap | $40: needs you. $60: stopped, over the cap | ✓ Passed2 checks |
A $40 launch from an agent at $230 of its $275 cap, with all agents at $318, then at $380, against a $400 company cap; then the agent at $250 of its $275 capevaluateAction › sums every agent's daily budget against the company's daily cap; an agent's own cap still applies to it alone | $358 in all: needs you. $420 in all: stopped. At $250, its own cap stops the $40 launch alone | ✓ Passed3 checks |
A raise and a cut once the month’s spend has reached the monthly capevaluateAction › blocks increases once the monthly cap is reached, but allows decreases | The raise is stopped; the cut goes to you | ✓ Passed2 checks |
An agent’s caps can only tighten
An agent’s caps and limits sit on top of the company’s. Whatever that layer asks for, a cap or limit can get stricter, never looser. Permission levels are different: an agent’s own levels are set on the agent itself.
| The case | Expected | Result |
|---|---|---|
The agent layer asks for a higher daily cap, no monthly cap and a 50% change limitthe agent layer may only tighten › caps take the minimum; a null or larger cap can't loosen | It keeps the company’s caps and its 20% limit; a stricter contact limit applies | ✓ Passed4 checks |
A $120 daily cap on an agent, where the company sets nonethe agent layer may only tighten › an agent cap applies where the company has none | The $120 cap applies | ✓ Passed1 check |
A layer that may only tighten asks to loosen a permission level and to turn the stop button offthe agent layer may only tighten › permission levels take the most restrictive, and the stop button can only turn on | The stricter level holds, and the stop button stays on. (An agent’s own permission levels don’t go through this layer: they’re set on the agent.) | ✓ Passed4 checks |
A playbook allows $1,000 a day, the company $400, and the agent asks for $600the agent layer may only tighten › resolveAgentConfig = playbook and tenant set, agent tightens | $400 a day | ✓ Passed1 check |
An agent’s settings ask for a looser reallocation limit than the company’sthe agent layer may only tighten › the reallocation limit can only tighten, through every layer | It keeps the company’s limit; only a stricter one applies | ✓ Passed6 checks |
An agent’s budget cap
What an agent may be given, against what the company allows.
| The case | Expected | Result |
|---|---|---|
Agent settings above and below a $60 company cap and a 3-a-week contact limitcaps › an agent's cap never exceeds the company's, and settings can only tighten | Above is refused with the reason; below is saved | ✓ Passed7 checks |
The guardrail checks
The checks every ad, email, budget and audience change goes through before it reaches you.
| The case | Expected | Result |
|---|---|---|
An email checked without consent data or the library’s claimsguardrail checks › reports checks it can't measure as not_enforced, never as a pretend pass | Those checks read “not checked”, never “passed” | ✓ Passed3 checks |
An email brand review passed, rewrote and held; one it never reviewed; brand review turned off; a budget changeguardrail checks › reads brand review's verdict on the ad or email: passed, rewritten (adjusted) or held (stopped), and stops one never reviewed | Passed, adjusted with the rewrite’s note, stopped with why, and stopped as not reviewed yet. Turned off it reads “Off”. A budget change has no words to review | ✓ Passed7 checks |
An email with the footer, one written differently, one without the link, one without the address, one with neither, and a company with no address on fileguardrail checks › stops an email without an unsubscribe link or the company's postal address, read from the email itself | The first two pass; every other one is stopped, naming what’s missing. The address’s numbers aren’t figures that need a source | ✓ Passed7 checks |
An email to 10,000 people, 10% without consentguardrail checks › computes audience adjustments from measured shares | 1,000 left out, and the reach counted after it | ✓ Passed3 checks |
An email to 1,860 customers from a store that suppresses subscribers, do-not-contact and open orders or tickets, but not sales conversationsguardrail checks › removes only the suppression lists the company switched on, in registry order, and spares customers on a lifecycle email | 149 on a subscription, 19 do-not-contact and 37 with an open order removed; existing customers are left out only from an acquisition agent’s email | ✓ Passed2 checks |
An email with some checks measured and some notguardrail checks › counts every check it lists in the summary | The summary’s passed, adjusted and not-checked counts add up to every check listed | ✓ Passed2 checks |
A banned word, a 20% discount where none is allowed, and an action the agent isn’t allowedguardrail checks › blocks banned words, discounts when none are allowed, and actions the agent may not take | Each one stopped | ✓ Passed3 checks |
A raise to $230 a day for an agent capped at $210guardrail checks › spend limits use the resolved config, where the agent's cap can only tighten | Stopped: “Daily budget would reach $230, above the cap of $210.” | ✓ Passed5 checks |
A reallocation between campaignsguardrail checks › checks a reallocation: the total against the spend limits, each campaign's move against the reallocation limit | The total is checked against the spend limits, and each campaign’s move against the reallocation limit | ✓ Passed8 checks |
One proposal already decided and one still waiting, after the budget has since movedguardrail checks › measures a decided proposal against the total it was proposed on, a pending one against today's | The decided one is measured against the total it was proposed on, the waiting one against today’s | ✓ Passed2 checks |
An email with a banned phrase from an agent set to Acts silently, proposed and then approved by a personguardrail checks › runs every check when a proposal is made, whatever its permission level, and again before it executes | Stopped both times, naming the phrase; a clean email goes ahead on its own | ✓ Passed5 checks |
A $30 raise when two agents run $200 and $190 a day, then when the second is retiredguardrail checks › measures the company's daily cap on every agent together, retired ones aside | $420 for all agents: stopped. With the retired agent left out: allowed | ✓ Passed2 checks |
A budget change on a platform whose tracking alert is open; a pause there; the alert fixed; a change on another platformguardrail checks › holds changes on a platform while its tracking alert is open, but lets pauses through | The change is stopped until the alert is fixed; the pause and the other platform’s change aren’t held | ✓ Passed5 checks |
An email to 9,500 people, 10% of them in Honolulu, sent at 9 a.m. New York time; a blackout date; a weekend; people messaged 20 hours agoguardrail checks › schedules a send around send days, blackout dates and quiet hours, and counts the people who wait | 950 sent after quiet hours, the blackout and weekend days skipped, and 190 sent once the 24-hour gap has passed | ✓ Passed8 checks |
An audience of 10,900 people against minimums of 1,000 and 20,000, and one with no sizeguardrail checks › measures the minimum audience on the audience's size, and says when it wasn't given | Passes 1,000, stopped at 20,000; with no size it reads “not checked” | ✓ Passed3 checks |
“9 in 10” from a sourced claim, the same claim with no source, and a “20%” no claim backsguardrail checks › needs every figure in an ad or email to come from a claim with its source | Only the sourced figure passes; the others are stopped, naming the figure | ✓ Passed5 checks |
Saving your limits
What the guardrail settings refuse to save, so a limit can’t be set to something meaningless.
| The case | Expected | Result |
|---|---|---|
The default limitsvalidateGuardrails › accepts the defaults | Saved | ✓ Passed1 check |
A $20,000 daily cap under a $10,000 monthly capvalidateGuardrails › refuses a daily cap above the monthly cap | Refused | ✓ Passed1 check |
A 90% change limit, or a 75% discountvalidateGuardrails › refuses a step size or discount that isn't offered | Refused | ✓ Passed2 checks |
A contact limit of −1, or quiet hours from 25:00validateGuardrails › refuses negative counts and bad quiet hours | Refused | ✓ Passed2 checks |
A monthly cap in euros for a company that pays in dollarsvalidateGuardrails › refuses caps in another currency | Refused | ✓ Passed1 check |
Who may approve
Roles and approval limits: a person can approve only what their limit covers.
| The case | Expected | Result |
|---|---|---|
Approvals of $5,000, $50 and $150 a day, by the owner and by an approver with a $100 limitwho may decide › enforces roles and approval limits; the owner is unlimited | The owner may; the approver may approve $50 but not $150, and is told why | ✓ Passed6 checks |
Who may give access
Who can give someone a role, and with what approval limit.
| The case | Expected | Result |
|---|---|---|
The owner makes someone an admin, then a second ownermayGrant › lets an owner give any role and limit, but never a second owner | Admin: yes. Second owner: refused | ✓ Passed2 checks |
An admin with a $500 limit gives limits of $100, $1,000 and nonemayGrant › keeps an admin within their own approval limit | $100: yes. $1,000 or unlimited: refused | ✓ Passed4 checks |
An approver tries to give someone accessmayGrant › refuses approvers and viewers | Refused | ✓ Passed2 checks |
The library gate
Agents can use only approved images and copy, and a claim only with its source.
| The case | Expected | Result |
|---|---|---|
An ad using an approved image, a headline and a sourced claimthe using gate › lets approved items through (claims with their source), and actions that use no library items | Allowed | ✓ Passed2 checks |
A retired image, a claim with no source, a deleted item and an unapproved draftthe using gate › refuses retired items, unsourced claims, missing items and loose drafts, naming the item | Each refused, naming the item and why | ✓ Passed5 checks |
A creative-desk draft, before and after you approve its deliverythe using gate › never lets a draft through, whatever the making desk's level: a delivered draft waits for its delivery's approval | Refused until approved, then usable | ✓ Passed2 checks |
A headline a person wrote and approved, containing a banned phrasethe using gate › refuses copy with a banned phrase, whoever wrote it, and keeps it from agents | It stays in the library, flagged, but no ad or email can use it and agents never see it | ✓ Passed5 checks |
A library of approved, draft, retired and unsourced itemsthe using gate › calls an item usable only when it's approved, not retired, and (for a claim) sourced | Only the approved, sourced ones are offered to agents | ✓ Passed2 checks |
Calling a test
A test is called once, at its planned end, at 95% confidence with enough conversions on every side.
| The case | Expected | Result |
|---|---|---|
10 against 15 conversions, then 40 against 80experiment statistics › calls a winner only with enough conversions and 95% confidence | “Too early to call”, then a winner | ✓ Passed5 checks |
A 14-day test already over 95% on days 0, 1, 7 and 13experiment statistics › gives no verdict before the planned end, even above 95% | “Reading so far”, never a verdict | ✓ Passed3 checks |
The same test on day 14experiment statistics › calls the winner at the planned end when the bar and the minimums are met | Winner found | ✓ Passed3 checks |
A test at about 87% confidence, and one where a side has fewer than 20 conversions, on day 14experiment statistics › calls no winner at the planned end when the bar or the minimums are not met | No winner: the current version stays | ✓ Passed7 checks |
Source: packages/core/src/core.test.ts, packages/core/src/agents.test.ts, packages/core/src/domain.test.ts, packages/core/src/setup.test.ts, packages/core/src/desks.test.ts, run with Vitest 5.0.5. To judge the quality of the agents’ decisions as well as their limits, read how agents are evaluated.
Read the record, then try to break a limit in the demo.
Join the beta, or try the demo first.