fix(push): stop offering a teammate's update back as a local edit (#823) - #827
Merged
Merged
Conversation
|
No findings. The PR description documents sufficient testing for this runtime change, including representative real-CLI verification. Per instruction, I reviewed only the specified diff and did not run or build the PR code. |
…ncent#823) Three more ways push could list a copy the member never edited as modified, ready to send a teammate's change back as the old version. Single-repo mode (item 2). Push runs against a knowledge worktree whose team root is <wt>/.teamai, a subdirectory of the git repo. The pre-push sync read each base version with `git show <rev>:rules/x.md`, which git resolves from the repo root, so it never found one, and every rule or skill a teammate updated read as a local edit. The three reads now pass `./<path>`, which git resolves from the working directory, as getFileContentWhenAdded and the agent guard already did. Placed agents (item 3). An agent placed with --role/--project is held when it changed on the team since this machine's copy was current, and "current" meant the version at the shared lastPullRev, which a pull in another checkout moves past a copy a stale worktree still holds (the Tencent#812 revert, for agents). The guard now reads this checkout's bases through checkoutBaseRevs, and falls back to the shared lastPullRev for a checkout with no entry, as the pre-push sync does. Push bases record where the sync moved rules and skills, not agents, so the copy stays at the revision pull delivered: the guard holds an agent that differs from its version at any base. Push records the team HEAD as a base before the scan, and the file there is always the current one, so the version the agent was added with is compared too whenever a base predates it; otherwise a placement that landed after the last pull would go back over a teammate's later edit. The hold message now says "this checkout". Skill copy (item 5). The sync overwrote a local skill in place, so a copy that failed partway left files from two revisions, matching no base, and the next push listed the skill as modified. The update is now built in a hidden sibling (the local copy, then the team version over it, so files only the member has survive as before) and renamed into place; a failure leaves the previous version whole. The stage carries the local modes, so cleanup makes a read-only stage writable before removing it, and warns with the path if a leftover cannot be removed; if the previous version cannot be renamed back, the error names where it is. Item 4 (user-scope push base) follows once Tencent#814 is merged.
SaulMoro
force-pushed
the
fix-823-push-sync-followups
branch
from
September 25, 2026 10:12
0302ab4 to
51c4b75
Compare
|
No findings. The PR description documents sufficient testing for this runtime change, including representative real-CLI verification. I reviewed only the specified diff and did not run, build, or install the PR code. |
jeff-r2026
self-requested a review
September 25, 2026 12:15
jeff-r2026
approved these changes
Sep 25, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Push could still list a copy the member never edited as modified, ready to send a teammate's update back as the old version. This fixes three of the paths #823 lists.
Before / After (real CLI,
teamai --dry-run push):origin/mainf558b94).teamai/rules/team-rule.md, noteamai pull[rules] team-rule (modified)[agents] vr (modified)Skipped vr: ... changed on the team since this checkout last synced itType of Change
Causes:
repo.localPath = <knowledge-wt>/.teamai, andgit showresolves paths from the repo root, so no base was ever found.lastPullRevis moved by a pull in another checkout (the [bug] push from a stale worktree diffs against another checkout's revision and can revert a teammate's update #812 revert, for agents). Push bases mark where rules and skills were synced, not agents, so any differing base counts. Push records the team HEAD before the scan, so the added-with version is also compared when a base predates the placement.Test Plan
npx tsc --noEmitpassesnpx vitest runpasses: 316 files, 4964 passed, 1 skippedNew tests, all red on
origin/main(f558b94) or under ablation:Ablations, repeated after the rebase onto 21cb76a: each change was reverted alone and its test failed at the expected assertion. That covers the
./prefix, agents.ts, the added-with fallback, the staged copy and the cleanup chmod. Three assertions inpre-push-sync.test.tspinned the buggy argumentrules/..., and now say./rules/....Build/Result:
npm run buildok. E2E run (--retry 0): the new file, pluspush-stale-worktree-812,push-namespace-e2e,role-scoped-agents,namespaced-entries,project-agent-cold-start,e2e,multi-projectandcopilot-agents: 9 files, 84 passed, 22 skipped (the skipped ones need a remote). The full e2e suite was not run.Real CLI, before (origin/main f558b94) and after (this branch)
Provider
git(local bare remote), agent Claude. Other providers and agents are left to CI.Related Issues
Part of #823 (items 2, 3 and 5; item 4 follows once #814 is merged)
Notes for Reviewers
Reproduced with the real CLI: items 2 and 3 (above).
From reading the code, covered by unit tests only: item 5. The partial-copy failure is forced by a mocked
copyDir, plus a real read-only skill.git merge-treeof this branch with fix(data-layout): let every self-mode worktree publish learnings and keep its queue (#808) #814's head (628f797) reports only the conflicts fix(data-layout): let every self-mode worktree publish learnings and keep its queue (#808) #814 already has withmain(CHANGELOG.md,src/contribute.ts,src/recall.ts), none from this branch.candidates === recorded); the guard now compares them with this checkout's bases like the rest..<skill>.<pid>.<hex>.teamai-prev; a failed restore names that path. A read-only subfolder can leave a leftover, and the warning names it..teamai/rulesis itself a scan source. A branch that has not merged a teammate's update lists its older copy as modified. That is why the item 2 test fast-forwards the branch. It is tracked in [bug] Follow-ups to the worktree fixes: import --from-mr never shares its learning, and push can still revert a teammate's update #823.push.tsand the agent guard (it belongs inpull.ts, which fix(data-layout): let every self-mode worktree publish learnings and keep its queue (#808) #814 changes).