Skip to content

[bug] Team members with different roles overwrite each other's blocks in shared root AGENTS.md #945

Closed

Description

@SaulMoro

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 discovery

Use 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 no rules path. 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 the claudemd/ 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, and README.th.md consistent. 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.md is 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.md only 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 root CODEBUDDY.md, .hermes.md, and AGENTS.override.md. Preserve that user choice. TeamAI must not create another file that changes the choice.
  • claude-internal, tclaude, codex-internal, and tcodex need 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 project AGENTS.md as 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 root AGENTS.md remains byte-for-byte identical after either member's pull.
  • At closure, shared root AGENTS.md contains 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.md intact. Project-scope delivery changes only project targets. The Claude-fallback case adds no duplicate blocks.
  • Oh My Pi still loads ~/.agents/AGENTS.md and 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

  1. changed the title [-][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[/+] on Oct 1, 2026
  2. changed the title [-][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[/+] on Oct 1, 2026
  3. SaulMoro commented on Oct 1, 2026

    @SaulMoro
    CollaboratorAuthor

    How #940 (Codex, #938) fits this issue:

    • User scope: the blocks go to $CODEX_HOME/AGENTS.md, beside the user-scope rules. Only Codex reads that file.
    • Project scope: the blocks come from the same session-start hook as the project's rules, with a SubagentStart entry for fresh subagents and nothing added on resume. Nothing goes to the project AGENTS.md.
    • fix(rules): give Codex the team rules: session hooks in a project, its own AGENTS.md in user scope #940 gates Codex's blocks on installation through settings (instructionFileInstallProbe), because Codex has no rules path. The shared target resolver proposed here can replace that check.
  4. changed the title [-][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[/+] on Oct 1, 2026
  5. changed the title [-][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[/+] on Oct 1, 2026
  6. self-assigned this
    on Oct 1, 2026
  7. 27 remaining items

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions