Upstream merge (crow <- zed)¶
crow is a fork of zed-industries/zed. Dev branch: acp-v2; PRs target main.
Remotes: origin = odellus/zed (ours), upstream = zed-industries/zed.
Prime directive: never let a merge silently revert crow -> zed. Upstream's
tests passing is NOT enough — a Crow->Zed string revert compiles clean. The
gate is the fitness function; only fit merges reach main.
The divergence model (know what you're protecting)¶
| Cat | What | Risk | Protect via |
|---|---|---|---|
| A net-new crow files | the product (agent_ui/workspace_agent_threads.rs, agent_ui/agent_thread_item.rs, client/atproto_auth.rs, mock_pds.py) |
~none | presence/registration tests; never delete |
| B rewired shared files | ACP-panel UI + auth gut (agent_ui/agent_panel.rs, agent_ui/agent_ui.rs, client/client.rs, client/user.rs, http_client) |
high | characterization tests on behavior |
| C cosmetic rebrand | "Zed"->"Crow" across ~80 files + icons | high-freq, silent | grep integrity scan |
| D feature | typst preview | low | localized tests |
Full protected path list: references/protected-files.md.
Procedure¶
1. Fetch and measure¶
cd <zed repo>
git fetch upstream --tags --force --quiet
git rev-list --count HEAD..upstream/main # how far behind
git merge-base HEAD upstream/main # our fork point
script/upstream-watch already digests this daily to
~/.agents/notes/dev/upstream-zed-digest.md — read it first.
2. Triage incoming commits by protected area¶
git --no-pager log --oneline HEAD..upstream/main
# which protected files does the incoming work touch?
git --no-pager diff --name-only HEAD...upstream/main > /tmp/incoming.txt
grep -Ff <(sed -n 's/^ - //p' references/protected-files.md) /tmp/incoming.txt
3. Merge¶
Prefer a merge commit over rebase (keeps crow's 6 commits intact, history honest):
Resolve conflicts in favor of crow's character for B/C, then:4. Run the gate (NON-NEGOTIABLE)¶
- Pass -> commit/keep the merge. - Fail ->git merge --abort (or reset), dump the failing guard + diff. Do
NOT push red. A guard may only be overridden if the merge replaces the
behavior with a superior method that still satisfies the guard's intent —
that's a human/judged call, never auto-approved.
5. (Future) Open PR against main¶
Once gated-green, the agent opens a PR acp-v2->main. Human reviews the PR,
not the raw merge. Eventually cron launches this whole flow; the gate is the
selection pressure that lets it be safe.
The gate (script/crow-merge-gate)¶
Passes iff ALL hold:
1. cargo check workspace clean.
2. Rebrand integrity: no Zed / zed.dev / cloud-URL resurrection in
Category-C files (grep against manifest). Icons re-asserted (checksum).
3. Crow characterization tests pass (Category A/B/D behavior guards).
4. Crown jewels present: Category-A paths exist and are registered.
Status: gate script + characterization tests are TODO — see strategy doc "Open decisions" for the proposed fitness-function seed. Until they exist, run steps 1-2 by hand and eyeball B.
Rules of engagement¶
- Merge often, merge small. A 20-commit tactical merge beats a 200-commit catch-up.
- Never
git revertcrow work to "make the merge clean." - A clean compile is necessary, never sufficient.
- When upstream and crow both touched a B-file, understand upstream's intent before resolving — sometimes their fix is good and we want it, adapted.