Get started
Core concepts
Main, worlds, merges, agents, rules and history: the few ideas the rest of the docs build on.
SoonThese pages describe Chronos Cloud, which opens from the waitlist. Running Chronos yourself? Self-host docs
Main
main is the database your app serves: what DATABASE_URL connects to, and where every merge ends up. Your app writes it directly, as it would any Postgres. Agents are taught to change it only by merging a world into it. With a merge policy, or in production, that is the only way they can.
Worlds
A world (also called a branch: the two words mean the same) is a copy of the database an agent works in. Forking one is instant whatever the size: it shares every row with its source and stores only what it changes. Writes in a world never touch main or any other world.
- Nested: a world can be forked from a world, as deep as you like, and reads as fast as
main. - Named and identified: a name (
fix-prices, reusable once the world is gone) and an ID that never is (wand 16 hex digits). - Owned: a world an agent forks is its own (
owner). Metadata of your own rides along: a task, a ticket, a run id, up to 64 KB of JSON. - Finished one of two ways: merged into its parent, or discarded. Merging part of it, or into another world, leaves it open.
- Shared counters:
serial, identity and sequence numbers belong to the database, not a world, so rows inserted in two worlds never collide when both merge.mainmay see gaps where a world took numbers.
Reading a world is just connecting to it: its name is the Postgres database name (/fix-prices in place of /main), or the branch of an MCP tool. See Worlds.
Merging
A merge compares three versions of every row the world changed: the row when the world forked (base), the world’s row now (ours), and the parent’s row now (theirs).
| The parent since the fork | The merge |
|---|---|
| didn’t change the row | applies the world’s version |
| changed it too, even to the same value | a conflict: the world computed its write from a value that’s gone. Nothing merges until it’s settled |
| added a row with the same unique value, or deleted a row the world references | refused with the Postgres error (23505, 23503): both sides were valid alone, not together |
A merge is all or nothing. Conflicts come back as data (each row’s base, ours and theirs), and you settle them: keep ours or theirs, combine rows column by column where the sides changed different columns, give a row by hand, or redo the work on a fresh fork. See Diff and merge.
Agents
An agent is who acts on the database, with a name, a secret token, and only the rights it was given. On Chronos Cloud each person gets one agent per project, named claude-<login>-<project>, made the first time their coding agent connects: everything it does is logged under that name.
| Right | Lets it |
|---|---|
read | read any world |
fork | make worlds, which are its own |
write_own | change the worlds it forked |
write_main | reach main: with merge_own, its merges may land there |
merge_own | merge the worlds it forked |
merge, restore, admin | merge any world; restore and undo; manage agents and rules. Not given to coding agents on Chronos Cloud |
Every write is in the audit trail as the agent’s, and UNDO AGENT name SINCE '-2 hours' puts back everything one agent changed, leaving everyone else’s changes alone.
Rules: policies and checks
Two kinds of rule run inside every merge, on the rows it is about to apply:
Merge policies: rules about the change
Given to an agent: “at most 500 rows”, “no deletes”, “never payments”, “no schema changes”. A merge that keeps to its agent’s policy lands on its own; one that breaks any rule is refused (42501) with every rule it broke, and its world waits for a person. A policy only ever takes rights away. See Merge policies.
Merge checks: rules about the data
A query that must find nothing in what the merge would make: “every list keeps at least one lead”. It runs on the merged result, so two changes that are each fine alone but break the rule together are caught. Rows found refuse the merge (23514), for everyone, people included. See Merge checks.
create merge policy careful with (max_rows = 500, max_deletes = 0, review_tables = 'payments');create merge check lists_keep_leads on tables (leads, lists) as select id from lists where id not in (select list from leads);Reviews
A world held by its policy waits in Reviews (in SQL, SHOW REVIEWS) with the reasons, its changes per table (deletes first), its version when the agent asked, and whether the agent wrote more since. A person approves it by merging it at the version they read, or rejects it by discarding it. An agent can’t remove a world from the queue, or merge it until a person does.
Development and production
Each project is in one of two modes, set in Settings or with chronos cloud production on|off:
| Mode | Its agents may | Use it while |
|---|---|---|
| development | read, fork, write_own, write_main, merge_own: merge their own worlds into main, under their policy if they have one | you’re building, and the data isn’t anyone else’s yet |
| production | read, fork, write_own: every world with changes waits for a person | real users depend on the data |
Your app’s DATABASE_URL writes main directly in both modes.
History
Chronos keeps every version of every row for the retention window (on the free plan, the last hour). Any table can be read as it was (select * from orders as of '-15 minutes'), a world can be put back to a moment or a named checkpoint, a merge can be undone, and so can everything one agent did. Undo writes the old rows back as an ordinary change, so it can itself be undone, and rows someone changed since are named rather than overwritten. See Time travel and undo.
Versions
Every write to a world moves its version on. A review, a diff and a dry run all say which version they read, and a merge can name it (MERGE WORLD w AT VERSION 12): if the world changed since, nothing merges. That is how an approval approves exactly what the person read, even while the agent keeps working.
Writes to main and merges are on disk before they return. Writes to other worlds are batched for speed; if the server stopped before they were saved, the world’s next merge says so instead of merging less than was written.