Master Sync (keeping your local master current)
Developer infrastructure, not an end-user Omniscio feature: the one in-app job that keeps this machine's local `master` branch current with everyone else's work on GitHub. It runs every 15 minutes by default, needs no setup, and only ever spends a "merge agent" session when a conflict genuinely needs a judgment call — capped at a number you control per day. The same page covers the catch-up road: what to run when you are too far behind for the sync to finish.
What it is
If you are developing Omniscio itself — not just using it — your computer keeps its own local copy
of this repository's master branch. Other developers (and the automated systems that land
finished work) are constantly adding commits to the shared copy on GitHub. Master Sync is the job
that keeps your local copy current with that shared copy, automatically, without you ever running a
manual git pull.
It is developer / repo-maintenance infrastructure, not something an ordinary Omniscio user (someone who just runs the finished app) ever sees. If you are working on Omniscio's own code, though, it is running in the background right now.
The problem it solves
Two things are true about a machine that develops Omniscio at the same time: your local master is
usually AHEAD of GitHub (work has been finished and landed locally but not yet published), and it is
also BEHIND GitHub (other people's work keeps arriving that you do not have yet). Left alone, that
gap only grows — and the more it grows, the more likely two people's independent changes touch the
same lines, which is what a "merge conflict" is. A small, frequent catch-up keeps the gap small and
keeps conflicts rare and easy; a large, rare catch-up produces large, painful conflicts.
Master Sync exists so nobody has to remember to do this by hand, and so that when it truly cannot resolve something on its own, it says so instead of silently falling behind.
Where to find it
Dev Pipeline panel → Setup tab. Two controls live there:
- Master sync — a toggle, OFF by default: it can buy paid merge agents, so nothing runs until you
switch it on. Turning it off again stops the job from touching your local
masterat all (it does not stop the app from telling you when you have fallen behind). - Merge agents per day — a number, 100 by default, from 0 to 1,000. This is the most "merge agent" sessions (see below) the job may buy in one calendar day before it stops buying more and simply waits for the next day. It keeps resolving things for free the whole time; only the paid half of its work pauses.
Nothing else needs to be set up. The job registers itself the first time you run the app from this repository.
How it behaves
Every 15 minutes
The job wakes up, checks how far behind GitHub's master your local copy is, and if it is behind at
all, brings the missing work in. Three things can happen to any one file that changed on both sides:
- No real disagreement. Most of the time, GitHub's changes and your own local changes touch different files, or touch the same file in ways that combine cleanly. This is folded in immediately, every time, with nobody involved.
- A disagreement a fixed set of rules can settle. A handful of very common, very safe patterns (for example: one side's copy already contains everything the other side changed) are resolved automatically, for free, by deterministic rules — and every answer is checked line by line before it is used, so no line either side added is ever dropped.
- A genuine conflict. Two people changed the same lines in ways that do not obviously combine. This is the only case that costs anything: the job buys a "merge agent" — a Claude session whose only job is to look at that one conflict and decide the right combination — up to the daily cap above. Once a conflict like that is solved, the answer is written down, so if the identical conflict is ever seen again on this machine, it is applied instantly instead of being paid for twice. (Sharing agreed answers between different developers' machines is the next piece of work, not part of this one — but one rule for it is already built in: while a disagreement over an open pull request is being settled, the computer that wrote the pull request keeps its own changes until the final answer lands, so its developer can keep testing; every other computer takes the interim answer.)
Nothing is ever held up waiting on the slowest conflict. Everything that is already resolved reaches
your local master right away; only the files still being decided stay on hold, and those catch up
the moment their merge agent finishes.
What never happens
- Nothing is ever pushed to GitHub by this job. It only brings GitHub's work IN to your machine. Publishing your own work outward is a separate, explicitly-approved step.
- A failed run never turns the job off. If one 15-minute attempt hits a problem, it simply tries again next time — it does not need anyone to notice and restart it.
- Your own working files are never touched or put at risk. The job does its work in an isolated copy of the repository, not the one you are actively editing in, so a messy or mid-edit checkout never blocks it and is never affected by it.
When it needs your attention
Master Sync raises a small number of dashboard/inbox notices, each only when it is actually true:
- The job has stopped firing. If an entire hour passes with no run at all, one notice appears pointing you back to the Setup tab.
- Today's merge-agent budget is used up. Once the daily cap is reached, one notice appears; free resolution keeps happening regardless, and paid work resumes the next day (or as soon as you raise the cap).
- You have fallen behind and something is genuinely waiting on a decision. This is the ordinary "conflict" notice — it names the files involved.
Every one of these notices clears itself automatically once the underlying condition is no longer true; none of them needs to be dismissed by hand for the system to keep working.
Checking on it yourself
A repo developer (or an AI agent working in the repository) can read a scorecard of how well the whole system is doing — how current machines are staying, how often the same conflict gets solved twice (it should never), how much is being spent, and so on — by running:
npm run scripts:run -- sync:standards
This is a read-only report; it changes nothing.
The catch-up road (when you are too far behind to sync)
Master Sync above is the everyday job. This is what to reach for when it cannot finish, because your
local master has drifted too far from GitHub's for a merge to be sensible.
When you are on it. Your local master has its own commits that GitHub does not have, and it
is many commits behind. Both are true at once — the histories have diverged. Master Sync would have
to merge across all of it; the catch-up road instead saves your work, puts you back on GitHub's
exact state, and republishes the work properly.
What it does, in order.
- Saves your work. Every commit your local
masterhas and GitHub does not is put on a dated branch namedcatch-up/<timestamp>, and the branch is then read back — its tip and commit count are reported. If the read-back does not confirm what was written, the road stops there and does nothing else, because the next step is the one that cannot be undone from memory. - Puts you on GitHub's exact state. It fetches the objects your store is missing (by their
ids, never a lazy fetch), then moves local
masteronto GitHub's commit, and proves the result by comparing the two tree fingerprints. An exit code is not accepted as proof. - Republishes the work. The saved commits are handed to the existing PR road, which cuts real PR branches on the current trunk — never whole-file copies from an old base, which is what silently reverted newer work in October 2026.
- Validates before publishing. Every PR is checked first: does the merged result still parse, hold one copy of each declaration, and import only names that exist? Does it delete any line the trunk still has? A PR that fails either is held with the reason, not published.
- Reviews, then announces. Each surviving PR is reviewed before it is announced.
It plans before it acts. Running it changes nothing until you tell it to perform — a reset of
local master is not something to do on a first look.
How to run it. It lives behind the existing PR door, so there is no new command to learn:
npm run pr:catch-up -- --catch-up # the plan — changes nothing
npm run pr:catch-up -- --catch-up --act # park, reset, and name the replay lanes
What it refuses, and why each refusal is a feature.
- No backup read-back → it stops. Resetting over work that was not actually saved destroys the only copy.
- The reset's tree proof disagrees → it stops and prints the exact command that puts your
masterback. - Every saved commit is generated output (index files, catalogs — the
chore(settle)commits the app writes itself) → it parks and resets, then replays nothing, and reports that as a success. Generated files never ride a PR, so there is genuinely nothing to republish. - A PR would remove a line the trunk still has → that PR is held, with the lines named.
For agents
What lives where (for repo-access agents)
- The job itself —
scripts/ops/sync-escalate.mjs, run by an in-app cron every 15 minutes (--apply --escalate). - The one switch — the
masterSyncEnabledapp setting (default OFF); the daily spend number ismasterSyncAgentDailyCap. - The catch-up road —
scripts/ops/catch-up.mjs, reached throughnpm run pr:catch-up -- --catch-up(dry-run) or-- --catch-up --act. Its three steps live inscripts/lib/catch-up-park.mjs(save + read back),catch-up-reset.mjs(hydrate + move + prove) andcatch-up-validate.mjs(the pre-publish gate). - The contract — master-sync-contract.md is the present-tense source of truth for what this system owes: every sync lands, a conflict is solved exactly once, nothing is ever lost, and it stays out of the developer's way. The catch-up road's own promises are in trunk-at-scale-contract.md, Process 2.
- The map — master-sync-map.md is where the moving parts, the main flow and the traps live for anyone about to change this system.
Related
- Markdown merge driver — a different, smaller piece of the same problem: it auto-resolves the single most common kind of conflict inside one file, before a merge ever runs.
- git-guardrails.md — the rules that keep every shared branch safe around a merge like this.
Last verified 2026-10-04