Skip to content

[bug] self-mode push behind main: a skill edited on both sides overwrites main's change #1326

Closed

Description

@SaulMoro

What happens

#1234 made a single-repo teamai push from a checkout behind the default branch stop with exit 2 when a file under .teamai/ changed both in the checkout and on the default branch. A skill is a directory, and that check only matches files. So a skill edited on both sides is still pushed over the teammate's change.

Reproduction

Built CLI on main (6c57c3b7), self mode, local bare remote:

  1. The member pushes .teamai/skills/demo/SKILL.md. The team merges it, and the member updates.
  2. A teammate appends teammate fix to .teamai/skills/demo/SKILL.md on main. The member does not pull.
  3. The member appends author change to the same file and runs teamai push --all.
Found 1 resource(s) to push:
    1. [skills] demo (modified)
branch diff vs main:
M	.teamai/skills/demo/SKILL.md
SKILL.md on branch has teammate line: 0
SKILL.md on branch has author line: 1

The same steps with a doc or a rule stop with exit 2 and push nothing. If only the teammate changed the skill, it is not listed and the branch keeps the teammate's line, so that case is fine.

Why

itemsChangedOnDefaultBranch (src/push.ts:1076) looks up each item's source in the per-file git diff between the merge-base and the tip. A skill item's source is the directory .teamai/skills/<name>, so the lookup finds nothing and the item passes unchecked.

Two related agent-format cases

Both come from converting a placed agent between .md and .yaml on a checkout behind the default branch.

  • A false stop on the member's own file. The member's earlier push --role ops added agents/ops/sample.md and was merged after their HEAD. They ran teamai pull but not git pull. Converting sample.md to sample.yaml stops with exit 2, saying the push "would delete .teamai/agents/ops/sample.md, which changed on origin/main". No teammate touched it: the retiring check compares no blob. git pull clears it. Comparing the tip with the blob this machine delivered (a delivered blob in the agent placement record, as docs already keep) would let it through.
  • A deleted agent comes back. When the default branch deleted the placed agent, the scan does not set supersedes, because src/resources/agents.ts:264 requires the placed file to exist at the tip. The conversion is pushed as a new agents/ops/sample.yaml, which re-adds the agent the team deleted. It shows as an explicit add in the PR, so review can catch it.

Possible fix

For skills, classify each file under the skill directory the way single files are classified (per-file blobs from the same diff, git hash-object for the member's copy). Treat the skill as edited when any of its files changed on both sides.

Activity

  1. SaulMoro commented on Oct 24, 2026

    @SaulMoro
    CollaboratorAuthor

    This was generated by AI during triage.

    Status: the skill case is fixed in #1333, now merged. A skill edited on both sides stops with exit 2 and pushes nothing. The two agent-format cases, the false stop on the member's own file and the deleted agent coming back, are fixed in #1339, which is approved and waiting on a rebase. Neither PR closes this issue on merge, so I'll close it when #1339 lands.

  2. SaulMoro commented on Oct 26, 2026

    @SaulMoro
    CollaboratorAuthor

    This was generated by AI during triage.

    Status: the two agent cases here are covered by #1339, and the skill case by #1333 (merged). #1339 was approved earlier, but its latest head refuses a conversion even after the member carries a teammate's change in, so changes are requested again. This issue closes when #1339 merges.

  3. added a commit that references this issue on Oct 26, 2026
    8116777
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinghelp wantedExtra attention is needed

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions