Chronos/DBWaitlist

Worlds

Merge policies and reviews

Approve rules once. Merges that keep to them land on their own; the rest wait for a person.

SoonThese pages describe Chronos Cloud, which opens from the waitlist. Running Chronos yourself? Self-host docs

Reviewing every agent’s diff works for ten changes a day and breaks at ten thousand. A merge policy changes what a person approves: you approve the rules once, and review only the merges that break them.

How it works

an agent merges a world
MERGE WORLD w  ├─ may the agent merge w at all? (merge_own or merge; write_main for main) ── no ──> refused  └─ inside the merge, holding its locks, on the exact rows it is about to apply:       does the agent keep to a merge policy?         no  ─────────────────────────────────────────> merged         yes: every rule kept? ── yes ────────────────> merged                               └─ no ──> refused (42501), every broken rule named;                                         the world stays, queued in Reviews                                           a person: read it, then Merge (at the version read) or Discard
  • What’s checked is what merges. The rules run inside the merge, on the rows it applies, under its locks: nothing written a moment before or after can slip past.
  • Stale work doesn’t win. A merge that would overwrite rows main changed since the fork needs a person, unless the policy allows overwrite.
  • The queue says when it’s out of date. Each held world records its version when the agent asked; changed_since says the agent wrote more after.
  • A policy only takes rights away. An agent needs merge_own to merge at all; the policy decides which merges need a person. An agent keeping to a policy changes main only by merging: a direct write, RESTORE or UNDO there is refused, since it would skip the rules.

Start here: no delete lands on its own

Whatever else a policy says, start every agent with max_deletes = 0. A wrong update leaves a row you can see and fix; a wrong delete leaves nothing to look at. Most agents rarely delete, so the queue stays short, and each delete that comes through shows you whether to trust the agent with more.

SQL, in the dashboard’s SQL editor
create merge policy agents with (max_deletes = 0);alter agent "claude-ada-shop" set (policy = 'agents');

The rules

Every rule is optional. A rule left out limits nothing, except schema, overwrite and critical, which start on the safe side.

RuleA merge needs a person whenDefault
max_rowsit changes more rows than thisno limit
max_deletesit deletes more rows than this; 0: any deleteno limit
rows_per_hourwith the agent’s other merges into main in the last hour, it changes more rows than thisno limit
deletes_per_hourthe same, for deleted rows: an agent can’t get past max_deletes by splitting a jobno limit
confirm_deletes_overit deletes more rows than this, and the person approving must type the countno count
max_ageits world was forked longer ago than this ('1h', '30 minutes')no limit
tablesit changes a table not in this list ('orders,items')any table
review_tablesit changes any table in this listnone
review_columnsit changes any column in this list ('users.email,accounts.owner'), even in one rownone
schemafalse, and it changes a table itself, a view, function, sequence, schema or typefalse
overwritefalse, and it overwrites rows its parent changed since the forkfalse
criticalfalse, and it changes a column a reader marked critical readsfalse
check_readstrue: its agents’ worlds record what they read, and a merge that read rows changed since waitsfalse
require_scopetrue: its agents must declare may_change or tenant when forkingfalse
max_effects, effects_per_hour, review_channelsit queues more effects (emails, webhooks, payments sent once it lands) than allowed, or any on a listed channelno limit
reviewernever itself: names an agent that decides held merges before a personnone
  • Counting: one per row the merge inserts, updates or deletes in the parent, after ONLY TABLES/ONLY KEYS. A row settled USING THEIRS changes nothing and doesn’t count; indexes, constraints and counters never do.
  • Names: read as SQL reads them: orders folds to lowercase, "Orders" quoted is another table.
  • Hourly rules: a sliding hour of the agent’s own merges into main; merges between its worlds count when they reach main, and a person’s approval doesn’t count.
  • Merge checks: a broken merge check is one more broken rule for an agent with a policy: its world is queued with the rows the check found.

Give a policy to an agent

On Chronos Cloud each person’s coding agent is claude-<login>-<project> (SHOW AGENTS lists them; the Policies page shows who keeps to what). Make the policy, then give it:

SQL
create merge policy careful with (max_rows = 500, max_deletes = 0, review_tables = 'payments');alter agent "claude-ada-shop" set (policy = 'careful');show merge policies;
StatementDoes
CREATE MERGE POLICY name [WITH (…)]a new policy
ALTER MERGE POLICY name SET (…)the rules named change; the rest stay. null removes a limit
DROP MERGE POLICY name [CASCADE]refused while an agent keeps to it, unless CASCADE releases them in the same step
ALTER AGENT name SET (policy = 'name')the agent keeps to it from its next merge; policy = null for none
SHOW MERGE POLICIESevery policy and its rules

The review queue

A held merge tells the agent why, and the agent stops and reports it (on a production project the answer carries the review’s link):

what the agent gets
merging bot_bulk needs a person's review (merge policy careful: it changes 6 rows (at most 3)); it's queued (SHOW REVIEWS)

The dashboard’s Reviews lists held worlds, oldest first. In SQL, SHOW REVIEWS:

ColumnMeaning
world, owner, policythe world, the agent that forked it, the policy that held it
reasonsevery rule it broke: changes 6 rows (at most 3); deletes 2 rows (at most 0)
asked, versionwhen the agent asked, and the world’s version then
changed_sincethe agent wrote more, or part was merged, after it asked: read the diff again
changesper table: deleted, updated, inserted, the tables that delete most first
scopewhat the world declared it would change, if anything
  • Approve: Merge in the dashboard, or MERGE WORLD w AT VERSION n. It lands only if the world is still at the version you read.
  • Approve part: MERGE WORLD w ONLY TABLES (orders) or ONLY KEYS (…); the rest stays queued.
  • Reject: Discard, or DROP WORLD w.
  • Email: owners and members are emailed when a world starts waiting (one email per version), unless they turn it off under Team → Notifications.

The agent can’t skip the queue: the hold is kept where only the database writes it, so the agent can’t clear it or merge the world until a person does, or until it fits the rules.

Confirming big deletes

With confirm_deletes_over = 100, a merge deleting more than 100 rows waits, and the person approving must give the count, counted from the merge’s own plan:

SQL
merge world cleanup confirm deletes 4812;-- a missing or wrong count is refused (55000) with the real one, before anything is written

A dry run’s notice gives the CONFIRM DELETES n that approves it. An agent can’t give the count for its own merge.

A reviewer before a person

Rules first, a reviewer model next, a person for what’s left. Name an agent as the policy’s reviewer; it reads each held merge and decides, with a reason:

SQL
alter merge policy careful set (reviewer = 'critic');-- as critic (or the MCP tools reviews, diff and review):review world bot_bulk approve reason 'a duplicate of lead 4';     -- merged, as it was heldreview world bot_refund reject reason 'lead 2 has an open deal'; -- not merged; a person sees whyreview world bot_odd pass reason 'not sure: check the deal';     -- left to a person
  • Approve merges at the held version; a world written to since is refused (40001). A big delete under confirm_deletes_over still needs a person’s count.
  • Reject and pass leave the world queued with the decision in its reviewer column. A person can overrule any decision.
  • Decisions are in the audit trail: SHOW AUDIT FOR AGENT critic.

Tuning and measuring

SQL
alter merge policy careful set (max_rows = 100);       -- the named rules change; the rest stayalter merge policy careful set (max_deletes = null);   -- null: no limitalter agent "claude-ada-shop" set (policy = null);     -- its rights alone decide nowshow merge outcomes;                                   -- how each agent's worlds endedshow merge outcomes by policy;

SHOW MERGE OUTCOMES counts, within the history window, how each agent’s worlds ended (merged on the rules alone, approved, rejected, discarded, still open) and how often merges were held, conflicted or refused. rules_rate is the share of decided worlds that merged on the rules alone: low means the rules hold too much; people undoing what passed means they hold too little.

Try rules before you set them

The MCP tool check_merge_policy runs rules against a world’s real changes and says whether its merge would land or wait, and why. Nothing is saved, so “what if max_rows were 1000?” is one call.

Recipes

AgentPolicyWhy
Any new agentmax_deletes = 0nothing it deletes lands without you
Support bot fixing ticket typostables = 'tickets', max_rows = 20, max_deletes = 0it can’t reach anything else, or delete
Pricing agenttables = 'prices', max_rows = 200, max_deletes = 0, review_tables = 'prices_history'routine repricing flows; history rewrites wait
Data-cleaning jobmax_rows = 5000, max_deletes = 50, deletes_per_hour = 200, confirm_deletes_over = 500deleting is its job: bounded, not banned
Anything near moneymax_deletes = 0, review_tables = 'payments,refunds,payouts'every change to money has a person on it
Migration assistantschema = true, max_deletes = 0, review_tables = 'payments'may change tables; deletes and money wait
Many agents, one tableleave overwrite = falsean agent that forked earlier can’t clobber a newer write
Identity and billing fieldsreview_columns = 'users.email,accounts.owner'a quiet wrong value there does more harm than a loud delete

From an agent

ToolDoes
merge_policiesthe policies, and which agent keeps to each
check_merge_policytries rules on a world’s real changes
reviewsthe queue
set_merge_policy, drop_merge_policynot listed for coding agents: only an admin sets rules (you, in the SQL editor or on the Policies page). An agent can propose rules and test them with check_merge_policy, never apply them
Merge policies and reviews · Chronos