Repository navigation
[bug] Team members with different roles overwrite each other's blocks in shared root AGENTS.md #945
Description
Problem
Two members of the same team can receive different claudemd/ instructions for the same project because their roles select different active knowledge namespaces. Writing a member's resolved selection into the shared root AGENTS.md makes project instructions depend on who last ran teamai pull.
For example, both members belong to the same team and work on the same project. The namespace names below are examples.
| Member's role | Resolved claudemd/ namespaces |
Result if the blocks go into shared root AGENTS.md |
|---|---|---|
| Developer | common and development |
A pull writes the developer's selection into the shared file. Committing it records that role's selection as project instructions |
| Product | common and product |
A pull replaces the generated block with the product member's selection and creates a diff in the same project file |
The shared root AGENTS.md cannot be the canonical delivery target for these member-specific instructions. Each member needs their own resolved selection alongside the project's common authored guidance. Merging every role into one block would also change the selection contract: each member would receive instructions from roles they do not have.
The current destinations also cause delivery bugs. A pull writes culture, claudemd/, and recall blocks to files several tools read. Some tools load the same blocks twice. Oh My Pi's targets hide the AGENTS.md files people write by hand.
| Scope | Where | What happens |
|---|---|---|
| both | Hermes target AGENTS.md |
A pull writes culture and claudemd/ to ~/AGENTS.md and to the project AGENTS.md even when Hermes is not installed. Hermes has no rules path, and pull.ts checks installation only through rules. |
| user | ~/AGENTS.md, the Hermes and WorkBuddy target |
In a git repo under ~, neither Hermes nor WorkBuddy reads it. Other tools read it in projects under ~. WorkBuddy also adds recall there. |
| project | AGENTS.md, the Hermes, Pi, and WorkBuddy target |
Copilot CLI and CodeBuddy read the blocks in their own file and again in AGENTS.md. Cursor reads them in .claude/CLAUDE.md and again in AGENTS.md. |
| user | Oh My Pi ~/.omp/agent/AGENTS.md |
It hides ~/.agents/AGENTS.md. Oh My Pi keeps one user context file. |
| project | Oh My Pi .omp/AGENTS.md |
It hides the project AGENTS.md at the same directory level. Oh My Pi keeps one context file per level. |
This selection is part of the original resource contract. The commit that introduced claudemd/ already filtered by role and injected the result into each tool's configured instruction file. Claude's target was .claude/CLAUDE.md. The resource needs to load in each session, but its destination need not be the shared project root file.
Found while auditing rules delivery in #946. The existing evidence comes from real teamai pull runs on 6db9144f with a sandbox HOME, in both scopes. b2d3598b changes none of the paths involved. Oh My Pi 18.2.1 and Pi 0.99.2 discovery code and the CodeBuddy 2.160.0 CLI were run offline. Hermes, WorkBuddy 5.6.2, Claude Code 2.1.285, Copilot CLI 0.0.411, Cursor CLI 2026.09.22, and OpenCode 1.18.21 come from their source. The new delivery targets below are proposed and still need validation with the tools.
Proposal
Resolve and deliver TeamAI instructions for each member through their local tool targets or hooks. Keep the shared root AGENTS.md for the project's common authored instructions. Its contents must not change with the member's role or active namespaces.
<project-root> is the root of the project checkout or worktree receiving the resources. Project paths below are relative to it. <opencode-config-dir> is OpenCode's resolved user config directory, normally ~/.config/opencode.
pull(<project-root>)
resolve culture, claudemd, and recall for this member and project
- write the blocks into <project-root>/AGENTS.md and overlapping context files
+ update the instruction target of each installed, enabled tool
the tool loads <project-root>/AGENTS.md through its existing discoveryUse an always-on file when the tool can load it alongside the project's instructions without another tool also loading the generated blocks. Otherwise, use that tool's hook or extension. CodeBuddy and WorkBuddy share a project rules directory, so they use one copy.
Preserve culture compilation, verbatim claudemd/ content, namespace selection and replacements, scope inheritance, and recall enablement. These remain instruction blocks. Native rule files are a delivery format here, and must apply from the first model request. Do not turn the blocks into a skill or load them only after the agent opens a matching file.
After migration, regular pulls leave shared project instruction files byte-for-byte unchanged. That includes AGENTS.md and any existing root CLAUDE.md, CODEBUDDY.md, .hermes.md, or AGENTS.override.md. Creating a tool's generated file must not hide those files.
User scope
Keep the blocks in tool-owned user locations. Do not select ~/AGENTS.md or ~/.agents/AGENTS.md as generated instruction targets. Keep existing native user targets and honor the tool roots teamai already resolves. Personal symlinks between user instruction files are outside this issue.
| Tool | Today | Change |
|---|---|---|
| Hermes | ~/AGENTS.md |
A managed block in $HERMES_HOME/SOUL.md, beside the rules block teamai already writes there |
| WorkBuddy | ~/AGENTS.md |
~/.workbuddy/rules/teamai-context.md, always applied |
| Oh My Pi | ~/.omp/agent/AGENTS.md |
~/.omp/agent/RULES.md, loaded outside the single context-file slot |
| Claude Code, Copilot CLI, CodeBuddy, Pi | Their native user instruction files | Keep those targets, while removing duplicate delivery through the old shared files |
| Codex family | No instruction target on main; #940 adds one |
Keep the user target planned in #940, $CODEX_HOME/AGENTS.md, with the corresponding home for each variant |
| Cursor | No instruction target | An always-applied teamai-context.mdc in its user rules directory, subject to a loader test |
| OpenCode | No instruction target | <opencode-config-dir>/teamai-context.md, registered with an absolute path in the user config's instructions. Preserve existing config entries and leave both native and shared user AGENTS.md files intact |
Honor the tool roots teamai already resolves. A project pull must not replace a user-scope block with the project's selection.
OpenCode combines custom instructions with its native instruction files. Add the user-scope TeamAI file through that channel and leave <opencode-config-dir>/AGENTS.md intact. Preserve the existing native discovery and Claude fallback. Check for duplicate TeamAI blocks from that fallback before activating a second channel.
Project scope
AGENTS.md stays the project's shared instruction file. Each tool continues to load the project's authored instructions through its native discovery or an explicit Claude import. The generated TeamAI content goes elsewhere.
| Tool | Today | Change |
|---|---|---|
| Claude Code | Blocks in .claude/CLAUDE.md |
Managed blocks in <project-root>/CLAUDE.local.md, with a stable managed @AGENTS.md import. Leave text outside the blocks intact |
| Codex family | No instruction target on main |
Add these blocks through the hook delivery used by #938 and #940. Register SubagentStart for fresh subagents too |
| Cursor | No instruction target; it can read copies written for other tools | .cursor/rules/teamai-context.mdc with alwaysApply: true |
| Copilot CLI | .github/copilot-instructions.md |
Keep <project-root>/.github/copilot-instructions.md and its managed blocks. Preserve text outside the blocks; stop duplicating the blocks in shared AGENTS.md |
| CodeBuddy and WorkBuddy | .codebuddy/CODEBUDDY.md and project AGENTS.md |
One .codebuddy/rules/teamai-context.md, always applied. Both tools read it |
| OpenCode | No instruction target | <project-root>/.opencode/teamai-context.md, registered in instructions through <project-root>/.opencode/opencode.json. Leave root opencode.json and all user-scope files intact |
| Pi | Project AGENTS.md |
Extend teamai's existing Pi extension to add the selected blocks through before_agent_start, preserving Pi's original prompt |
| Oh My Pi | .omp/AGENTS.md |
An always-applied .omp/rules/teamai-context.md if it loads from both the root and subdirectories. Otherwise, use the existing OMP extension to add the blocks. The delivery choice remains open |
| Hermes | Project AGENTS.md |
A plugin system-prompt section resolved from the session's cwd. The size limit remains open |
The file names in this table are proposed dedicated targets. A same-named file that teamai does not own must be preserved and reported. If a target needs a discovery setting, keep that setting separate from the generated content and preserve the member's existing settings.
Claude reads AGENTS.md directly only when no project CLAUDE.md, .claude/CLAUDE.md, or CLAUDE.local.md takes precedence. The local target therefore needs the import. Import paths are relative to the containing file: use @AGENTS.md in root CLAUDE.local.md; @../AGENTS.md would apply to a file inside .claude/. Keep the managed import stable when the shared file is added or removed. TeamAI does not create AGENTS.md to satisfy it. Validate the present and absent cases during implementation, preserve authored imports, and verify that shared instructions reach the model once.
Copilot keeps .github/copilot-instructions.md and its existing loader. Removing the duplicate blocks from shared AGENTS.md leaves one TeamAI copy. No additional instruction directory or startup registration is needed.
OpenCode loads config files inside .opencode. Use that local config for the instruction reference, with a path whose resolution is checked from both the root and a subdirectory.
The recalled instructions still tell an agent with the teamai-recall subagent to use it. Tools without that subagent run teamai recall "<task>" directly. Update the stale comment above injectRecallBlockIntoTools that says Cursor, Codex, and WorkBuddy lack subagents.
Hooks and extensions
Reuse the existing hooks and adapters. Resolve the same member, project, and scope that a pull resolves. Deliver the blocks before the first model request, preserve the tool's own instructions, and keep the blocks through clear, resume, compaction, and fresh subagents where those events exist.
For Codex, follow #938's tested lifecycle. Add context on startup, clear, and compaction. Add nothing on resume when the history already holds it. Apply the same rule to these blocks without duplicating the team rules that #940 already delivers. Configure the context limit so the complete resolved content reaches the model.
For Pi and OMP, extend the adapters separately. Their prompt APIs differ. Add the blocks to the host's original prompt rather than accumulating a new copy on every turn.
init and doctor must name a missing discovery setting, an untrusted hook, or a size limit that prevents delivery. Writing the generated file is not proof that the model receives it. An unavailable channel must not fall back to shared AGENTS.md or report successful delivery.
Also in this change:
- Check installation for culture and
claudemd/even when the tool has norulespath. Reuse the scoped path and installation helpers, and make pull, local-agent delivery, recall toggles, uninstall, and doctor agree on the target. - Skip writes when the generated content is unchanged. Remove obsolete TeamAI blocks when the source becomes empty, a namespace becomes inactive, or recall is disabled.
- Keep one copy at the shared CodeBuddy and WorkBuddy target. Removing one tool must not remove the copy while the other still uses it.
- Update the affected usage guides and
skill-data/references. This changes delivery, not theclaudemd/resource format or namespace rules. Rules rendering remains in [bug] Team rules miss most tools: each tool's own rules format, else a file only it reads, else a hook or extension in project scope #946. - Review the affected capability cells in the README table after implementation. Change a checkmark or add a limitation only where verified support changes; copying a file is not proof of support. If an update is needed, keep
README.md,README.zh-CN.md,README.ja.md,README.ko.md, andREADME.th.mdconsistent. Leave unrelated cells unchanged.
Migration
The next pull removes complete TeamAI culture, claudemd/, and recall blocks from the old targets that no longer deliver them. Preserve everything outside those markers, including authored instructions, and leave malformed blocks intact with an actionable warning.
The old targets include ~/AGENTS.md, project AGENTS.md, ~/.omp/agent/AGENTS.md, project .omp/AGENTS.md, and the project Claude and CodeBuddy context files. Keep the blocks in Copilot's .github/copilot-instructions.md. Remove an empty file only when teamai can establish that it created the file.
Plan migration per old file. A tool-owned target can migrate once that tool's replacement channel is ready. A shared target can migrate once every installed tool that teamai wrote there has a tested replacement channel. Coordinate removal of the shared blocks and activation of the replacements so the same instructions are not active twice. If a replacement is unresolved, leave the old file intact and report incomplete migration. This pending state cannot satisfy the closing criteria, and the old shared blocks are not a permanent fallback. Dry-run reports the intended changes without writing files.
This one-time cleanup can change files earlier versions already modified. Name those files in the pull output. Once migration completes, later pulls do not rewrite shared project instruction files.
Known limits and open decisions:
- Oh My Pi currently reads project rules only when the session starts at the project root. A rules file alone does not meet this issue's subdirectory requirement. Choose and test the extension channel before closing the OMP part.
- OpenCode can load Claude's user instruction file when its native user
AGENTS.mdis absent. If that fallback already contains the TeamAI blocks, validate a channel that preserves authored instructions without adding a second copy. Until then, report the conflict; do not hide the fallback or modify a shared global file. - Hermes' plugin prompt sections accept at most 4,000 characters per section and 8,000 characters across all sections. A larger block needs another tested channel or an explicit unsupported result. Do not truncate it or move it into shared
AGENTS.md. - WorkBuddy reads the project
AGENTS.mdonly from the cwd, on the first turn, and only its first 8,000 characters. Moving TeamAI blocks out of that file removes their contribution to the cut, but does not change WorkBuddy's discovery of authored instructions. - Authored files can still take precedence over
AGENTS.md, including rootCODEBUDDY.md,.hermes.md, andAGENTS.override.md. Preserve that user choice. TeamAI must not create another file that changes the choice. claude-internal,tclaude,codex-internal, andtcodexneed separate checks of their discovery paths. Following a family layout is a proposal, not a completed test.- Older TeamAI versions can reintroduce blocks in the old targets. Document the team upgrade requirement; this migration changes the behavior of upgraded clients.
Outside this scope
Changing .gitignore, .git/info/exclude, global Git exclusions, or the Git index is outside this issue. TeamAI does not choose which generated resources a team commits.
Repairing or compensating for personal symlinks between native user instruction files is also outside this issue. For example, a member can link $CODEX_HOME/AGENTS.md to their shared ~/.agents/AGENTS.md. This issue does not add an alternative Codex user delivery channel for that configuration.
This change separates generated instruction targets from the project's authored instruction files. It lets a team exclude those targets later. Tracking generated targets, including Copilot's .github/copilot-instructions.md, can still commit one member's role selection for other members and create task diffs. Keeping Copilot's existing target is a deliberate scope choice. The clean task-diff check below assumes the team has chosen exclusions for the generated targets.
This issue does not move every other TeamAI resource or change how rules, skills, agents, or MCP are delivered. #946 owns rules delivery. #938 and #940 own Codex's hooks, which also deliver its project instruction blocks.
Done when
- TeamAI does not select
~/AGENTS.md,~/.agents/AGENTS.md, or shared projectAGENTS.mdas generated instruction targets. No new block is written directly to those paths or to another tool's context file. - After migration, regular pulls preserve the bytes of shared authored project instruction files, including when the member's role, active projects, or
claudemd/content changes. - A fixture with two members of the same team and project but different roles verifies that each receives their expected
claudemd/namespace selection. Their generated blocks differ, while the shared rootAGENTS.mdremains byte-for-byte identical after either member's pull. - At closure, shared root
AGENTS.mdcontains no member-resolved TeamAI blocks. Reporting an unsupported channel or an incomplete migration does not waive this requirement. - Each targeted tool receives culture, shared instructions, and enabled recall before its first model request, once, from the project root and a subdirectory. A tool with an existing delivery target retains tested delivery. An unsupported result cannot waive that requirement; new targets are validated or explicitly reported as unsupported.
- The blocks remain available after clear, resume, and compaction, and reach fresh subagents where supported. Codex resume adds no duplicate context.
- A pull writes blocks only for installed, enabled tools and preserves existing native instructions and discovery settings.
- User and project scopes keep their existing selection and inheritance semantics. A project pull leaves user-scope blocks intact.
- User-scope OpenCode blocks load from the separate configured file and leave its native user
AGENTS.mdintact. Project-scope delivery changes only project targets. The Claude-fallback case adds no duplicate blocks. - Oh My Pi still loads
~/.agents/AGENTS.mdand the project's authored instructions after its generated context files are removed. - Disabling recall, deleting an instruction source, and leaving a namespace remove the corresponding generated content from files and hooks.
- Migration coordinates all writers of each shared old target, removes complete blocks only after their replacement channels are ready, preserves authored text, reports malformed blocks and incomplete migrations, and introduces no duplicate active copy.
- fix(rules): give Codex the team rules: session hooks in a project, its own AGENTS.md in user scope #940's project-scope delivery follows these targets and does not reintroduce member-resolved blocks in shared root
AGENTS.md. - Uninstall and local-agent delivery use the new targets, including the shared CodeBuddy and WorkBuddy ownership rule. Doctor reports actual discovery requirements rather than file-copy success.
- With generated targets already excluded in the test fixture, a pull that updates TeamAI instructions leaves an existing task diff and the staged diff unchanged. The pull neither edits the exclusion files nor changes the index.
- The affected usage guides and
skill-data/references describe the new targets and their limits. The PR includes one representative real-CLI verification record from the build, with additional host coverage identified separately. - The affected README capability cells have been reviewed against the implemented delivery. Any necessary checkmark or limitation update is applied consistently in all five README languages and backed by validation. If the cells remain correct, record that no README change is needed.
Activity
[-][bug] teamai instruction blocks land in files other tools read, or hide AGENTS.md[/-][+][bug] Instruction blocks land in shared AGENTS.md files, and Oh My Pi's targets hide them[/+][-][bug] Instruction blocks land in shared AGENTS.md files, and Oh My Pi's targets hide them[/-][+][bug] Instruction blocks land in ~/AGENTS.md, load twice in project scope, and hide AGENTS.md in Oh My Pi[/+]SaulMoro commentedon Oct 1, 2026
How #940 (Codex, #938) fits this issue:
$CODEX_HOME/AGENTS.md, beside the user-scope rules. Only Codex reads that file.SubagentStartentry for fresh subagents and nothing added on resume. Nothing goes to the projectAGENTS.md.settings(instructionFileInstallProbe), because Codex has norulespath. The shared target resolver proposed here can replace that check.[-][bug] Instruction blocks land in ~/AGENTS.md, load twice in project scope, and hide AGENTS.md in Oh My Pi[/-][+][bug] Instruction blocks reach other tools, hide AGENTS.md, and rewrite shared project instructions[/+][-][bug] Instruction blocks reach other tools, hide AGENTS.md, and rewrite shared project instructions[/-][+][bug] Team members with different roles overwrite each other's blocks in shared root AGENTS.md[/+]fix(rules): keep Codex's project content out of AGENTS.md (Tencent#945)
fix(rules): give Codex the team rules: session hooks in a project, it…
fix(pull): write instruction blocks only for installed tools (Tencent…
fix(pull): plan instruction files before writing them (Tencent#945)
fix(pull): give Claude its project blocks in .claude/rules (Tencent#945)
fix(pull): give Cursor an always-applied teamai-context.mdc (Tencent#945
fix(pull): give CodeBuddy and WorkBuddy their own rule files (Tencent…
fix(pull): give Hermes its user blocks in SOUL.md (Tencent#945)
fix(pull): give Oh My Pi its blocks without hiding AGENTS.md (Tencent…
27 remaining items
fix(instructions): preserve unresolved blocks and shared tool state (T…
fix(instructions): preserve global Codex hooks and activation ownersh…
test(instructions): retry transient hook fixture cleanup (Tencent#945)
fix(uninstall): remove global adapters with the last install on the m…
fix(uninstall): keep global adapters on project uninstall and name th…
fix(uninstall): gate empty-plan exclusion and join E2E workers (Tence…
fix(instructions): honor exclusions and retained native blocks (Tence…
fix(pull): deliver each member's team instructions without the shared…
fix(rules): reconcile rules delivery with per-member instruction targ…
fix(rules): reconcile rules delivery with per-member instruction targ…
fix(rules): reconcile rules delivery with per-member instruction targ…
fix(rules): reconcile rules delivery with per-member instruction targ…
fix(rules): use native formats and scope-specific delivery (#957)
fix(antigravity): probe the tool's own roots, not the shared .agents/…