CROSS-REPO-SYNC-POLICY.md).
Repository Topology
Verify your remotes match:git remote -v. The commands below assumeencoreos= canonical andencoreos_lovable= the Lovable fork. If your clone names them differently, adjust accordingly.
Sync Direction (two-way reconciliation)
encoreos is canonical. Both repos stay active, so changes flow both ways
and converge to identical development tips:
- Lovable -> canonical: merge Lovable’s commits into canonical via a
CI-gated PR (
npm run sync:pull). - canonical -> Lovable: after that PR merges, fast-forward Lovable’s
developmentup to canonical (npm run sync:mirror).
git rev-parse encoreos/development and
git rev-parse encoreos_lovable/development resolve to the same SHA.
Commands
The scripts print outward commands (push /
gh pr create) rather than
running them — every remote write stays under human control.
Critical Rules
Never force-push development
Force-pushing development in either repo erases merged PR history — the #1
cause of lost work here (see the May 18 2026 incident below). The sync tooling
never force-pushes; sync:mirror only ever does a fast-forward and refuses
otherwise.
If you genuinely must reset: create a backup branch first
(git branch backup/development-YYYY-MM-DD), then proceed manually.
Pause Lovable during merges
lovable-dev[bot] pushes directly to the fork’s development. Merging
canonical PRs while Lovable is actively editing diverges the histories
immediately. Either pause Lovable editing before merging, or re-run
npm run sync:pull to fold Lovable’s latest in before mirroring.
Branch protection (recommended on both repos’ development)
- Block force pushes (most critical).
- Require PR reviews before merge (recommended).
- Require status checks (recommended).
Procedures
Drift check (run anytime)
Lovable -> canonical (bring Lovable work into canonical)
canonical -> Lovable (converge the fork after merging)
sync:mirror refuses if the fork has diverged again — run sync:pull first.
Never add --force.
Automation
.github/workflows/lovable-sync.yml runs weekly (and on demand). It performs
the Lovable -> canonical merge and opens/updates a lovable-sync PR (or a
conflicts-labeled PR with a checklist if the merge is no longer clean). It
never auto-merges and never pushes to the fork — the merge and the
mirror push stay human-driven, consistent with the repo’s “open PRs, humans
merge” policy. Requires repo secret LOVABLE_SYNC_TOKEN (read the fork +
open PRs on canonical).
Troubleshooting
sync:mirrorsays Lovable diverged / push rejected (non-fast-forward): the fork got new commits. Runsync:pull, merge that PR, thensync:mirror. Do not add--force.sync:verifysays NOT converged after mirror: the mirror push didn’t land — re-checknpm run sync:checkand re-run the push.
Incident: May 18, 2026 Force Push
On May 18 at 22:34 UTC,development on the Lovable fork was force-pushed from
a state with 14 merged Cursor PRs to a reconciliation commit that didn’t
include them. Root cause: the reconciliation PR was based on an older state of
development, and the force push replaced the post-merge state.
Recovery: all source branches were preserved; content was verified
file-by-file and recovered via PRs #362 (encoreos) and #71 (fork).
Prevention: block force pushes on development in both repos; the sync
tooling never force-pushes.