teamai-reports checkout conflict between user scope and project scope of the same single-repo (kind: self) team repo (variant not covered by #808)
Maintainers usually reply within 1 day
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 25/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Stale
- Tech stack
- git, gitlab, node.js, typescript
Research direction
Read the worktree path and eviction logic named in the report: getWorktreeDir, getDataHome, removeOldCheckoutsInDotTeamai, and ensureWorktree/openWorktree; compare how they handle user and project scopes. Reproduce the conflict with the listed steps, then check both teamai-reports and teamai-learnings from each scope. Done means the two scopes can use the repository’s side branches without leaving report data stranded; pull request #1465 is already open for this issue.
Written by the indexing model from the issue text.
Description
Title
teamai-reports checkout conflict between user scope and project scope of the same single-repo (kind: self) team repo (variant not covered by #808)
Body
Summary
On one machine, a single-repo (kind: self) team repo is installed at user scope, and running any teamai command inside that repo also auto-bootstraps a project scope partition for it. Both scopes publish teamai-reports / teamai-learnings, but they compute different side-branch worktree paths:
- user scope:
~/.teamai/reports-wt - project scope:
~/.teamai/projects/<workspace-slug>/reports-wt
Git allows a branch to be checked out in one worktree only, and the eviction logic is one-directional, so the project scope permanently locks the user scope out. Report pushes then fail non-blocking, so usage events accumulate locally without any visible error (unless debug.log is inspected) and never reach the reports branch.
This looks like a variant of #808 that #808 does not cover: #808 fixed per-checkout installs that each kept side-branch checkouts in their own .teamai/; here the two conflicting checkouts are the user-scope install and the project-scope partition of the same repo.
Environment
- teamai-cli: 0.27.0 (observed), and 0.28.0 (source compared; see below)
- Node.js: v22.23.3, macOS arm64
- Provider: self-hosted GitLab (gitlab provider), team repo in
mode: selfwithusageReport: true - Config:
- user scope:
scope: user,repo.kind: self,repo.localPath: <business-repo>/.teamai,repo.businessRepoRoot: <business-repo> - project scope (auto-created):
scope: project,projectRoot: <business-repo>, data home~/.teamai/projects/<workspace-slug>/
- user scope:
Steps to reproduce
- Install the single-repo team at user scope and
teamai pullfrom outside the repo.~/.teamai/reports-wtis created and holdsteamai-reports. - Run
teamai pull(or let the host's session-start hook run it) inside the repo. A project partition is bootstrapped and its pull refreshes its own checkout. Log:
The project-scope checkout at[reports] removed the old checkout at /Users/<user>/.teamai/reports-wt~/.teamai/projects/<slug>/reports-wtnow holdsteamai-reports. - Generate a usage event (invoke any skill), then
teamai pullfrom outside the repo again.
Actual behavior
The user-scope report fails non-blocking and keeps the data local:
[reports] update failed (non-blocking): Preparing worktree (checking out 'teamai-reports')
fatal: 'teamai-reports' is already used by worktree at
'/Users/<user>/.teamai/projects/<slug>/reports-wt'
Auto-report push was not confirmed; keeping local report data
~/.teamai/user-usage.jsonl keeps growing; nothing reaches teamai-reports. The state lasts until the project-scope checkout is removed manually. The same conflict class applies to teamai-learnings.
Expected behavior
One shared side-branch checkout per repository (as CheckoutRefusedError itself promises: "teamai now keeps that checkout at ${wt}, shared by every checkout of this repo"), or at least symmetric eviction so the next pull can take ownership.
Root cause
getWorktreeDir(localConfig, dirname)→getDataHome(localConfig) + dirname;getDataHome→config.dataHome ?? getTeamaiHome(scope).- Project configs get
dataHome = partitionHomefromanchorProjectConfig; user-scope configs keep~/.teamai(loadLocalConfigdoes not redirect akind: selfuser config to the partition). removeOldCheckoutsInDotTeamai(self mode) removes only checkouts whose resolved path ends with/.teamai/<worktreeDirname>. That matches the user-scope path (~/.teamai/reports-wt) but not the project partition path (~/.teamai/projects/<slug>/reports-wt). Hence:- project-scope pull can evict the user-scope checkout and take the branch;
- user-scope pull can never evict the project-scope checkout, because
git worktree addfails first.
Not fixed in 0.28.0
I compared 0.27.0 and 0.28.0 dist code for the paths involved: getWorktreeDir, getDataHome, usesBranchWorktree, ensureWorktree/openWorktree, removeOldCheckoutsInDotTeamai, loadLocalConfig. The relevant logic is unchanged, so #808's "they now live in the project partition that every checkout shares" appears to cover only the per-checkout .teamai/ variant, not user scope vs project scope.
Suggested fixes
- For
kind: selfconfigs, resolve the side-branch worktree dir from the shared project partition (resolveProjectDataHome(businessRepoRoot)) regardless of config scope (mirrors #808). - Or make the eviction symmetric: consider any checkout of the same repository's worktree dirname, not only paths under
/.teamai/. - Or, when
git worktree addreports the branch is checked out in another worktree of the same repository, adopt that checkout instead of failing (asopenWorktreealready does for valid existing checkouts). - At minimum, surface the retained-report state in
teamai statusso members notice.
Workaround used
Symlink the project-scope paths to the user-scope checkouts so openWorktree accepts the existing checkout:
ln -s ~/.teamai/reports-wt ~/.teamai/projects/<slug>/reports-wt
ln -s ~/.teamai/learnings-wt ~/.teamai/projects/<slug>/learnings-wt
plus a periodic script that removes the project-scope checkouts and runs teamai pull from outside the repo. Fragile and not upstream-able.
- Dominant language
- TypeScript
- Stars
- 5.6k
- Forks
- 471
- Avg merge
- 20h 16m
- Merged PRs (30d)
- 399
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from Tencent/teamai-cli
-
bug help wanted
Difficulty 3/5 1-2 days Newbie friendliness 64/100
Tencent/teamai-cli#1539 ·
Maintainers usually reply within 1 day
-
[bug] codebase --deep-enrich in a team repo reports success but never publishes, and leaves the team clone dirtyPossibly taken @Kiddo4993 claimed this today. Openbug help wanted
Difficulty 4/5 1-2 days Newbie friendliness 35/100
Tencent/teamai-cli#1537 ·
Maintainers usually reply within 1 day
-
Difficulty 3/5 1-2 days Newbie friendliness 70/100
Tencent/teamai-cli#1523 · 1 comment ·
Maintainers usually reply within 1 day
-
bug
Difficulty 4/5 3-5 days Newbie friendliness 38/100
Tencent/teamai-cli#1516 ·
Maintainers usually reply within 1 day
-
bug help wanted
Difficulty 4/5 3-5 days Newbie friendliness 45/100
Tencent/teamai-cli#1504 · 2 comments ·
Maintainers usually reply within 1 day
All issues in Tencent/teamai-cli
Similar issues
-
area:plugins area:security area:skills bug has repro
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
anthropics/claude-code#105911 ·
Maintainers usually reply within 1 day
-
openspec-apply-change skill: when blocked, may select a ready artifact unrelated to missingArtifactsOpen
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Fission-AI/OpenSpec#2165 ·
Maintainers usually reply within 1 day
-
🐞 bug 🧐 unconfirmed
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
Tencent/tdesign-vue-next#7032 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
gnosis/gnosis_vpn#661 ·
Maintainers usually reply within 1 day
-
content-freshness: staleOwnedContent doc comments still say 'complete receipt' (follow-up to #7912)Opentriage:bug-verified
Difficulty 1/5 Under an hour Newbie friendliness 92/100
Maintainers usually reply within 1 day