Repository navigation
fix(rules): give Codex the team rules: session hooks in a project, its own AGENTS.md in user scope - #940
Conversation
hermesRulesText becomes inlinedRulesText, the one renderer for tools that read rules from a single instructions file. It strips frontmatter and leads a path-scoped rule with 'Applies to files matching: <globs>'. Hermes SOUL.md and doctor's Hermes check use it. Part of Tencent#938.
Codex reads instructions from AGENTS.md, not from .codex/rules, so the copies pull wrote there never reached it (Tencent#938). The codex defaults drop rules and gain claudemd (AGENTS.md, ~/.codex/AGENTS.md at user scope). pullAllRules syncs a [teamai:team-rules] block into that file once per path while an enabled, installed Codex-family tool maps it, and removes it otherwise. syncManagedInstructions probes rules ?? settings, so a machine without Codex gets no ~/.codex.
Follows the T3 rename, so a path-scoped rule reaches AGENTS.md without frontmatter, after its Applies to line.
…tructions and recall Codex now reaches AGENTS.md through its default claudemd path; these tests pin user scope (~/.codex/AGENTS.md), a full project-scope pull writing all four teamai blocks into one AGENTS.md, and recall on/off. Also corrects the injectRecallBlockIntoTools comment, which listed Codex as skipped.
Uninstall strips the [teamai:team-rules] block and scans the legacy .codex/rules directory for teamai's copies. A shared instruction file now keeps only the blocks a remaining enabled, installed tool would write, so --agent codex drops the team-rules block while Pi keeps its own.
Codex reads no rules directory, so doctor now compares the team-rules block in each AGENTS.md an enabled, installed Codex-family tool maps with what pull renders. It fails on a missing or stale block, on an AGENTS.override.md that Codex reads instead, and on an entry with no claudemd path. The file list comes from RulesHandler, the same resolver the pull writes through.
Codex never read the <rule>.md copies teamai wrote to .codex/rules (and .codex-internal/rules, .tcodex/rules). Every rules sync now removes the ones that still hold what teamai delivered, including teamai-recall.md, keeps edited copies and names them, and leaves *.rules alone.
# Conflicts: # src/resources/rules.ts
…codex-rules-agents-md
…s-md # Conflicts: # src/resources/rule-format.ts
A CLI upgrade with the team repo unchanged takes the "Already synced" fast path, which never ran the rules sync. So a member upgrading from 0.22.0 got no team-rules block in AGENTS.md and kept the old .codex/rules copies until the repo moved or they ran pull --force. The fast path now runs the Codex part of the rules sync (block + reclaim) and nothing else.
… block The already-synced pull now rewrites the block, so the fix text no longer sends the member to pull --force.
codex-internal and tcodex drop their rules path and read team rules from AGENTS.md like codex. Codex-family instruction writers probe rules ?? settings ?? skills, so a team entry with neither rules nor settings no longer counts as installed. writesInstructionBlock is the one answer to which blocks a tool gets, shared by pull's writers and uninstall.
…fix/codex-rules-agents-md # Conflicts: # src/__tests__/codex-instructions-rules.test.ts
removeClaudeMdSection now reports whether it removed a section and can delete a file left holding only whitespace. The team-rules sync and recall off use it, so a pull that removed nothing no longer deletes a member's own empty AGENTS.md.
When every team rule is frontmatter only, pull writes no team-rules block, so a missing block is correct and an AGENTS.override.md shadows nothing. Also note that an empty override shadows AGENTS.md too.
Editing teamai.yaml moves the team repo, so a plain pull does the full sync; --force is not needed. Matches the other Codex block checks.
The summary and result lines said CLAUDE.md for every instruction file, including Codex's AGENTS.md. They now print the file's path under an 'Instruction-file blocks' heading.
recall on now asks the same question as pull's recall writer and uninstall, so the three cannot drift. No behavior change.
The tombstone cleanup walks toolPath.rules, which Codex no longer has, so a copy of a rule tombstoned after the member's last pre-Tencent#938 pull stayed forever. The legacy reclaim now removes tombstoned names too, keeping and naming a copy the member changed since delivery (Tencent#822).
…ninstall Parametrizes the project-scope legacy reclaim, the four Codex doctor failure cases and the full uninstall over the Codex family.
With Codex's default claudemd (Tencent#938), an HTTP prompt command reported by Codex writes the shared-instructions block into ~/.codex/AGENTS.md when ~/.codex exists, and creates nothing when it does not.
It reads a tool-neutral rule's paths: frontmatter, which both the Copilot renderer and the inlined-rules renderer use; it no longer lives in the Copilot module.
… goes Removing the last block deleted any instructions file it left empty, so an empty AGENTS.md a repository tracked was deleted once Codex was disabled or the team had no rules left. injectClaudeMdSection now creates a file as just the block, and deleteIfEmpty deletes only a file that opens with it; a member's empty file is written back empty. Also describe the per-block cleanup of shared instruction files in the deployed uninstall skill.
|
- uninstall and the legacy [teamai:rules] strip remove blocks through removeClaudeMdSection, so a member's empty AGENTS.md survives them as it does pull. Removing a block at the top of a file keeps the next one there, so a file teamai created still goes with its last block. - `remove rules` refreshes with the rules this member's pull delivers (role, project and tag selection) instead of every rule in the repo. - doctor reports a Codex team-rules block left behind when the team has no rules, and nothing else in that case. - teamRulesBlock strips the block markers wherever they appear in a rule, not only as whole lines, since the block is located by substring.
|
Findings
The previously reported legacy-recall, empty-file, filtered-refresh, doctor, marker-sanitization, and uninstall-skill documentation issues are resolved. The PR description contains sufficient real-CLI testing evidence. |
…claim legacyRuleCopies classifies each .codex/rules copy (and the codex-internal and tcodex dirs) as teamai's or edited, on the ledger, team-render, tombstone and shipped-recall proofs reclaimLegacyRuleCopies used inline. Read-only and public so uninstall can apply the same check. No behavior change.
…rules' copies Uninstall picked every .md in a legacy rules dir whose name matched a current team rule or a built-in, so it deleted copies a pull had kept as the member's edits, and left copies of rules the team had tombstoned. It now takes the legacy dirs from RulesHandler.legacyRuleCopies, the check pull reclaims by: owned copies go, edited ones stay and are named in one English warning. The tool's current rules dir is unchanged. Addresses the codex-review findings on Tencent#940.
|
Why the project
They already get the team rules in their own format, so a block there would reach them twice, and a So in a project Codex gets its rules and instruction blocks from teamai's session hooks, and in user scope from its own |
The project AGENTS.md the earlier revision wrote the rules into is read by Cursor, Copilot, OpenCode and Claude too, which already get the rules in their own format. The Codex family now gets them from the teamai session-start hook instead, and pull writes no rule file for it. - A team-rules handler adds the user-scope rules, then the cwd project's, as pull resolves them, skipping a scope that does not enable the tool. It adds nothing on resume, whose history already holds them. - A SubagentStart entry gives a fresh subagent the same rules. - Both entries set additionalContextLimit: 0; past 2,500 tokens Codex keeps only the start and end of a hook's context. - doctor checks the limit on the session-start entry; the AGENTS.md block check, its markers and its uninstall handling are gone. The block never shipped. - Culture, shared instructions and recall still go to AGENTS.md; the old .codex/rules cleanup and the remove-rules role filter are unchanged. For Tencent#938.
|
Codex now gets the team rules, and the culture, |
Tencent#942 pinned Codex's default paths before Tencent#938 moved its rules to the session-start hook: no rules path, and an AGENTS.md that follows the root in user scope.
The project AGENTS.md is the owners' file, and Cursor, Copilot, OpenCode and Claude read it too. The Codex family now takes its project content from the session hooks and its user content from its own AGENTS.md: - Project scope: no `claudemd` in the Codex-family defaults, so pull writes nothing to the project AGENTS.md. The session-start and subagent-start hooks add the project's rules plus the culture, claudemd/ and recall blocks, leaving out a block another tool already wrote into the project AGENTS.md. - User scope: the team rules go into a team-rules block of ~/.codex/AGENTS.md (and the variants' homes), beside the other blocks; the hook adds nothing outside a project. The "Already synced" pull writes the block too. - doctor checks that block in user scope, and both hook entries' limit in a project. uninstall removes the block. For Tencent#938.
|
Findings
All earlier findings are resolved in the current diff. The PR description includes sufficient real-CLI end-to-end testing evidence. |
|
Findings
All previously reported findings are resolved. The PR description includes sufficient real-CLI testing evidence. |
…encent#945) Rebased onto Tencent#940, which already moves Codex's project content to its session hooks. The rebase kept this branch's side in conflicting hunks; this commit restores what that dropped of Tencent#940 (teamRulesHandler, the fast-path Codex rules sync, uninstall's per-block retention and keptRuleFiles) and joins the two designs: - teamRulesHandler takes Codex's culture, claudemd and recall from resolveInstructionBlocks, as pull and the Pi, OMP and Hermes extensions do, and no longer skips a block found in the project AGENTS.md: pull removes those, and the skip handed Codex another member's stale selection. - The Codex family is a hook target in project scope, with AGENTS.md retired for a team override or an earlier build. Hook text drops block markers for every tool, as Tencent#940 did for Codex. - Uninstall keeps Tencent#940's per-block retention and clears through the planner; the team-rules block is one of the blocks cleanup knows. - An emptied file goes only when it opens with a teamai block, as Tencent#940 decided, and git does not track it. AGENTS.md now assert that nothing does and that uninstall clears the blocks left there.
… AGENTS.md (#945) (#952) * fix(pull): write instruction blocks only for installed tools (#945) Add src/instruction-targets.ts, one resolver for where the culture, claudemd and recall blocks go per tool and scope. Pull, recall enable/disable, local-agent and uninstall read targets from it. A pull now skips tools that are not installed, whether or not they have a rules path, so Hermes no longer writes ~/AGENTS.md when it is absent. It also strips teamai blocks from known targets no installed tool reads, and deletes the file when nothing else is left. Targets are unchanged. * fix(pull): plan instruction files before writing them (#945) Culture, claudemd and recall blocks now go through one planner that works out each file's content first. A pull no longer rewrites a file whose blocks are current, leaves a block with a missing or repeated marker alone with a warning, deletes an emptied file only when git does not track it, and reports the files it would change under --dry-run. Recall is part of the same pass, so a pull removes the recall block when recall is disabled, and recall enable/disable use the same targets. * fix(pull): give Claude its project blocks in .claude/rules (#945) Claude's project-scope culture, claudemd and recall blocks move from .claude/CLAUDE.md to .claude/rules/teamai-context.md. Claude loads that file from the root and from subdirectories, and still reads AGENTS.md and an authored CLAUDE.md the way it chose to; CLAUDE.local.md would have stopped the native AGENTS.md load. The next pull removes the old blocks from .claude/CLAUDE.md and keeps the rest of the file. teamai-context is excluded from the rules sweep and from push, so the file is neither deleted as stale nor pushed as a team rule. An e2e test pulls as two members of one project with different roles: each gets their own selection and AGENTS.md keeps its bytes. * fix(pull): give Cursor an always-applied teamai-context.mdc (#945) Cursor had no instruction target and only saw the blocks other tools left in AGENTS.md and .claude/CLAUDE.md. It now gets them in .cursor/rules/teamai-context.mdc with alwaysApply: true, in both scopes. Uninstall and local-agent go through the same planner as pull, so a teamai-context file is removed whole, header included, and is created with its header. * fix(pull): give CodeBuddy and WorkBuddy their own rule files (#945) CodeBuddy and WorkBuddy both read the project's .codebuddy/rules, so their project blocks share one always-applied .codebuddy/rules/teamai-context.md instead of .codebuddy/CODEBUDDY.md and the project AGENTS.md. WorkBuddy's user blocks move from ~/AGENTS.md to ~/.workbuddy/rules/teamai-context.md. Uninstalling one of the two keeps the shared copy while the other is installed. The shared AGENTS.md is cleaned only once no installed tool still targets it; Pi and Hermes keep it until their own channels land. * fix(pull): give Hermes its user blocks in SOUL.md (#945) Hermes' user-scope culture and claudemd blocks move from ~/AGENTS.md, which Hermes does not read from a project under the home directory, to $HERMES_HOME/SOUL.md beside the team rules block teamai already writes there. Only a user-scope pull writes them, so a project pull leaves them alone. Hermes counts as installed when $HERMES_HOME exists, the same check rules delivery uses, instead of a ~/.hermes probe. * fix(pull): give Oh My Pi its blocks without hiding AGENTS.md (#945) Oh My Pi keeps one context file per level, so ~/.omp/agent/AGENTS.md hid ~/.agents/AGENTS.md and .omp/AGENTS.md hid the project's AGENTS.md. User-scope blocks now go to ~/.omp/agent/RULES.md, an always-applied rule beside that slot. In a project, teamai's OMP extension asks the new `hook-dispatch instructions` event for the member's blocks when a session starts and appends them to each turn's system prompt; OMP rebuilds that prompt from its base every turn, so they reach each request once. The next pull removes the old blocks from both context files. Verified with OMP 18.2.1 against a local capture server: the blocks reach each request once from the project root and a subdirectory, and the project AGENTS.md still loads. * fix(pull): give Pi its project blocks through its extension (#945) Pi's project blocks went into the project AGENTS.md, the file every member shares. teamai's Pi extension now asks `hook-dispatch instructions` for the member's blocks when a session starts and adds them to each run's system prompt; Pi renders that prompt from its base for every run, so they do not pile up. The next pull removes the old blocks from AGENTS.md once no installed tool still writes there. User-scope blocks stay in ~/.pi/agent/AGENTS.md. * fix(pull): give Hermes its project blocks through a plugin (#945) Hermes' project blocks went into the project AGENTS.md even when Hermes was not installed. teamai now installs a Hermes plugin, $HERMES_HOME/plugins/teamai-instructions, enabled in plugins.enabled, whose system prompt section asks `hook-dispatch instructions` for the member's blocks for the session's directory. Hermes builds it once per session and keeps it through compression and resume. A section holds 4,000 characters; when the blocks are longer, pull says Hermes skips them instead of cutting them or falling back to AGENTS.md. With Pi, Hermes and WorkBuddy moved, no tool writes the project AGENTS.md any more, so the next pull removes the teamai blocks left there. Uninstall also cleans a tool's retired files. * fix(pull): give OpenCode its own team instruction file (#945) OpenCode had no instruction target and only saw the blocks other tools left in AGENTS.md. It now gets them in .opencode/teamai-context.md, listed in the instructions of .opencode/opencode.json, and in user scope in ~/.config/opencode/teamai-context.md, listed by absolute path in the user opencode.json. Only that entry is added or removed; the member's entries and the root opencode.json stay as they are. While ~/.config/opencode/AGENTS.md does not exist, OpenCode reads ~/.claude/CLAUDE.md, which already holds the user blocks when Claude is installed, so teamai adds no second copy and says so. Verified with OpenCode 1.18.21 against a local capture server: the blocks reach the request once from the project root and a subdirectory. * feat(doctor): check that each tool can load its team instructions (#945) doctor now asks what keeps a tool from loading this member's culture, claudemd and recall blocks, not whether a file was written: each file target must hold the current blocks, OpenCode's file must be listed in its instructions, the Pi and Oh My Pi extensions and the Hermes plugin must be installed as this build writes them (and the plugin enabled), the Hermes section must fit its 4,000-character limit, and no file an earlier release wrote may still hold blocks. * test(e2e): cover two roles with every tool, the task diff and content removal (#945) Three real-CLI tests for the closing criteria of #945: two members of one project with every file-based tool installed keep the shared AGENTS.md byte-identical across a role change and a claudemd edit; with the generated targets excluded by the fixture, a pull that updates the instructions leaves the task diff, the staged diff, the index and the exclude file unchanged; and disabling recall, deleting a claudemd source and leaving a namespace remove that content from files and from the extension's prompt text. Docs drop the remaining wording that named CLAUDE.md or AGENTS.md as the injection target, and the changelog asks teams to upgrade together. * docs(usage): name the Copilot limit of Claude's .claude/rules target (#945) * fix(pull): deliver Codex's blocks from the same source as every tool (#945) Rebased onto #940, which already moves Codex's project content to its session hooks. The rebase kept this branch's side in conflicting hunks; this commit restores what that dropped of #940 (teamRulesHandler, the fast-path Codex rules sync, uninstall's per-block retention and keptRuleFiles) and joins the two designs: - teamRulesHandler takes Codex's culture, claudemd and recall from resolveInstructionBlocks, as pull and the Pi, OMP and Hermes extensions do, and no longer skips a block found in the project AGENTS.md: pull removes those, and the skip handed Codex another member's stale selection. - The Codex family is a hook target in project scope, with AGENTS.md retired for a team override or an earlier build. Hook text drops block markers for every tool, as #940 did for Codex. - Uninstall keeps #940's per-block retention and clears through the planner; the team-rules block is one of the blocks cleanup knows. - An emptied file goes only when it opens with a teamai block, as #940 decided, and git does not track it. AGENTS.md now assert that nothing does and that uninstall clears the blocks left there. * fix(doctor): ask for OpenCode's instructions entry only once its file exists (#945) pull registers .opencode/teamai-context.md (or the user file) in instructions only after writing it, so a team with no culture or claudemd/ has no file and no entry. doctor failed that case. * fix(pull): address review of #945: retired files only, one OpenCode path, channel reports Standards and spec review, round 1: - Cleanup touches only the files earlier releases wrote blocks to, never a tool's current target: a member without Copilot no longer strips a tracked .github/copilot-instructions.md a teammate's pull wrote. - The OpenCode Claude fallback and the instructions registration live in instruction-targets.ts, so pull, recall enable, local-agent and doctor agree; a dry run reports the opencode.json change. - pull (after installing hooks) and init name a Pi or OMP extension or Hermes plugin that is missing, out of date or disabled, and Hermes text over its limit; "Synced" is printed for file targets only. - The Codex team-rules writer stays out of a project file when Codex's session hook carries the rules, even with a team claudemd override. - Uninstall decides which blocks a remaining tool keeps from its target, not from toolPath.claudemd. - One helper resolves hook text for both handlers; doctor and pull share the channel and limit checks and one Hermes plugins.enabled reader. - Docs: the destination table lists every tool and marks the channels no live session has checked; the misplaced rows leave the recall table; the uninstall text in both guides and skill-data describes the shared CodeBuddy/WorkBuddy file; the stale Codex dedupe sentence goes. * fix(pull): address review round 2 of #945 - Docs: pull cleans only the files earlier releases wrote, not a tool's current file; the Cursor and CodeBuddy notes say what the loader reads instead of claiming live delivery. - init reports instruction channel problems on every path that installs hooks; a silent session-start pull leaves them to doctor; a failed check no longer logs as a skipped hook reconcile; the fix names `teamai hooks inject`. - A dry run promises an OpenCode instructions entry only when it would write the file, and a failed registration points at doctor. - recall disable drops OpenCode's entry once its file goes; local-agent defers to OpenCode's Claude fallback only when Claude's file holds the blocks. - Tests: uninstall keeps the shared .codebuddy rule for a WorkBuddy entry without claudemd; the channel check names a missing Pi extension; recall enable writes no OpenCode copy beside the fallback. * feat(recall): tell tools without the recall subagent to run teamai recall (#945) Pi, Hermes and OpenClaw have no teamai-recall subagent, so they got no recall block. They now get one that tells the agent to run `teamai recall "<keywords>"` itself before code, debugging or design work, with the subagent block's skip conditions. It uses the same markers, so recall disable, uninstall, cleanup and doctor treat both blocks alike; each target and hook gets the one that matches its tool. Verified with Pi 0.99.2 against a local capture server: the block reaches each request once from the project root and a subdirectory. Pi's README row now shows learnings, codebase and teamwiki, the same criterion Hermes, OpenClaw and DeepSeek Harness already meet. * fix(pull): address review round 3 of #945 - OMP counts as installed for its team instructions only where ~/.omp exists, which is where teamai installs its extension: a member without OMP in a project that has .omp/ no longer gets a warning on every pull and a failing doctor check that hooks inject cannot fix. - The Hermes over-limit message names the recall block and `teamai recall disable`, since the recall block now counts too. - Uninstall keeps the recall block for every remaining tool on a shared file, as pull now writes one to every tool. - Tests: recall disable removes the direct block from Pi's hook text; a project with .omp/ and no ~/.omp reports no OMP problem. * fix(hooks): keep Codex's hook adding the member's blocks over AGENTS.override.md (#945) #947 taught the Codex session hook to skip a block already present in AGENTS.override.md. This branch removed that skip for AGENTS.md: a teamai block in a project instructions file holds whoever pulled last, so the hook adds the member's own selection instead. The rebase keeps that rule for AGENTS.override.md too, inverts #947's skip test, and drops the skip sentence from the unreleased #938 changelog entry. * fix(pull): address review round 4 of #945 - Retired files include the claudemd a team's toolPaths gives a tool whose target moved, so a team override such as claude.claudemd: CLAUDE.md no longer keeps another member's blocks after the upgrade. A path that is any tool's current target is never retired; uninstall keeps the blocks a remaining tool still writes there. - A team rule named teamai-context is not delivered, since it would land on teamai's own context rule file and block the instructions; pull names it. - OpenCode's instructions list teamai-context.md only while it holds teamai's blocks, so a same-named file of the member's is not activated; doctor asks for the entry under the same condition. * fix(pull): address review round 5 of #945 - The Hermes teamai-instructions plugin is written, enabled, disabled and removed only while its directory is absent or its plugin.yaml carries teamai's marker, so a member's same-named plugin survives inject and uninstall; pull and doctor name it. - Uninstalling OpenCode drops teamai's instructions entry even when the member's own text keeps teamai-context.md. - A file several tools share gets the teamai-recall subagent block only when every tool reading it has the subagent, so WorkBuddy without agents beside CodeBuddy gets the direct teamai recall block. - Removing a block that opened a file leaves no blank lines above the member's text. * refactor(hooks): share one ownership check for generated extension files (#945) generatedFileState(file, marker) says whether a file teamai generates into another tool's directory is absent, teamai's, or someone else's. Pi's extension and agent hooks, the Hermes instructions plugin and the Oh My Pi extension use it on inject and remove. Oh My Pi had no check: inject overwrote and uninstall deleted a same-named ~/.omp/agent/extensions/teamai-hooks.ts of the user's. Now inject skips it with a warning and uninstall leaves it. * fix(pull): keep the configured claudemd for a tool without a rules directory (#945) A team toolPaths entry may omit rules, and an entry does not inherit the defaults. Claude Code (project), Cursor and WorkBuddy (user) then had no teamai-context target while their configured claudemd counted as retired, so pull removed the blocks and delivered them nowhere. contextRule falls back to the configured claudemd; a claudemd is retired only when it is not the tool's current target; and only a teamai-context file takes the entry's header and teamai ownership, so the configured file stays the member's. * fix(pull): address review round 7 of #945 - A copy of a team rule named teamai-context an earlier release delivered to a rules directory is removed when the record shows it unchanged or it matches the team rule's render, so the instructions can take that path; an edited copy stays and the instruction sync names it. - A toolPaths entry with only claudemd is probed through that file's directory, and a bare file such as AGENTS.md counts as installed, as before. - Project CodeBuddy and WorkBuddy keep their configured claudemd when the entry has no rules, like Claude Code and Cursor. - The HTTP local agent's claudemd sync strips the blocks earlier releases left in files no installed tool reads now, as pull does. - Uninstall drops teamai's OpenCode instructions entry whenever the config lists it, also after the context file was deleted or stripped. * fix(pull): address review round 8 of #945 - The HTTP local agent's project prompts reach Pi, OMP and Hermes: a machine-level `instructions` handler adds the agent's cached claudemd for the session's project, and the sync counts such a tool as reached once its extension or plugin is ready. - The HTTP sync probes each tool through its own paths, as pull does, so a WorkBuddy-only project without .codebuddy/ gets its prompt. - OpenCode treats ~/.claude/CLAUDE.md as its fallback while that file holds teamai blocks, also ones an excluded Claude Code left there, so it no longer loads a second copy; pull warns that nothing keeps them current. - A test resolves targets for every tool, scope and toolPaths shape (full, without rules, only claudemd, only settings): an installed tool with a claudemd keeps getting the blocks, and no target is retired. * fix(pull): address review round 9 of #945 - OpenCode registration leaves an instructions entry alone while its teamai-context.md is a file of the member's: pull no longer drops an entry the member listed for their own file. - The HTTP prompt sync acks failed, with the reason, when the planner leaves a target unchanged (a file teamai did not write, a malformed block) instead of counting the tool as reached. - Hermes counts as reached only while the project's instructions, team blocks plus HTTP prompts, fit its 4,000-character section. * fix(pull): address the adversarial review of #945 against main - The HTTP prompt sync strips an old instruction file only when every installed tool that wrote it received this sync's instructions, so a CodeBuddy prompt no longer removes Claude's blocks from .claude/CLAUDE.md. - A rule tombstone named teamai-context no longer deletes the instruction file the unchanged-revision pull just refreshed. - A placed namespaced rule named teamai-context keeps its namespaced path instead of landing on teamai's instruction file. - Codex project HTTP prompts reach Codex through its SessionStart and SubagentStart hooks; the cache handler is named http-prompt-instructions so the HTTP reporter wiring stays one handler per event. * fix(pull): address review round 10 of #945 - A Codex project HTTP prompt is delivered when Codex is installed for the member: its hooks are user-level, so a project without .codex/ still reaches it. - Uninstall leaves OpenCode's instructions entry for a teamai-context.md that holds none of teamai's blocks: that file is the member's. * fix(pull): address review round 11 of #945 - Pi counts as installed for project instructions when ~/.pi exists: teamai installs its extension there, so a project needs no .pi/. - teamai records the OpenCode instructions entry it adds, and uninstall removes a recorded entry even after the member stripped the markers from the context file. * fix(pull): address the second adversarial review of #945 against main - The unchanged-revision pull reclaims an earlier release's copy of a team rule named teamai-context before syncing the instructions. - Uninstall removes only this checkout's recorded OpenCode entry, and forgets the entries it removed. - Rule removal skips the teamai-context file that holds teamai's blocks, so a targeted uninstall keeps a shared instruction file. - Codex is probed at the member's recorded tool root. - The HTTP ack fails when OpenCode's config cannot list the prompt file. - A prompt whose HTTP delivery fails leaves the cache as it was, so session hooks do not read it. - The HTTP agent records state in the project's data home. * fix(pull): address review round 12 of #945 - Pull restores the alwaysApply header of teamai's own rule file when it was lost or changed, so doctor no longer reports it current. - OpenCode's instructions entry is removed, by pull or uninstall, only when teamai recorded adding it. - A configured claudemd named teamai-context (no rules) is the member's file, in pull and uninstall. - Pull reports synced culture and instructions only when a target was reached. * fix(instructions): keep failed deliveries and removals retryable (#945) * fix(instructions): confirm replacements before retiring delivery (#945) * fix(instructions): preserve unresolved blocks and shared tool state (#945) * fix(instructions): preserve global Codex hooks and activation ownership (#945) * test(instructions): retry transient hook fixture cleanup (#945) * fix(uninstall): remove global adapters with the last install on the machine (#945) A project uninstall kept the Pi and OMP extensions, the Hermes plugin, Codex's user hooks and server-pushed agent hooks unconditionally, so that other projects keep their delivery channel. On a machine with no user scope and no other project, nothing removed them any more, unlike main: every Pi, OMP, Hermes or Codex session kept running teamai hook-dispatch after teamai was uninstalled. A project uninstall now keeps them only while the user config or another project partition exists, and the last install removes them. * fix(uninstall): keep global adapters on project uninstall and name them (#945) The previous commit removed the Pi/OMP extensions, the Hermes plugin, Codex's user hooks and pushed agent hooks when no user config or other project partition existed. That misses HTTP-only installs and self or legacy projects, whose config stays inside <project>/.teamai and cannot be enumerated, so one project's uninstall could cut another install off. A project uninstall keeps them again and its summary names each one, with `teamai hooks remove`, which removes them, as the step to run first when no other install uses them. pull --dry-run now previews the retired-file cleanup a real pull does after installing a Pi, OMP, Hermes or Codex adapter, unless a member's same-named file or a disabled Hermes plugin keeps that channel closed. * fix(uninstall): gate empty-plan exclusion and join E2E workers (#945) * fix(instructions): honor exclusions and retained native blocks (#945)
Summary
Codex never read the team rules:
pullcopied them to.codex/rules/, Codex's command-policy directory. Now Codex gets the rules, and the culture,claudemd/and recall blocks, from its ownAGENTS.mdin user scope and from teamai's session hooks in a project. The projectAGENTS.mdstays the owners' file.Green is new, dashed red is removed:
flowchart LR pull[teamai pull] old[".codex/rules/*.md"]:::removed userfile["$CODEX_HOME/AGENTS.md<br/>user scope: rules, culture,<br/>claudemd/, recall"]:::added proj["project AGENTS.md<br/>the owners' text only"] hook["teamai hook-dispatch<br/>session-start · subagent-start"]:::added subgraph codex [Codex session] start["startup · clear · compact"] sub["fresh subagent"] model[model context] end pull -.->|"copies today, Codex never reads them"| old pull -->|user scope| userfile userfile --> model proj --> model start --> hook sub --> hook hook -->|"additionalContext: the project's rules,<br/>culture, claudemd/, recall"| model classDef added fill:#2f8f4f,stroke:#1f6b39,color:#fff; classDef removed fill:#a33a3a,stroke:#7a2a2a,color:#fff,stroke-dasharray:4 3;The legacy cleanup shared by
pullanduninstallpreserves a tombstoned rule copy unless its recorded delivery hash matches. A missing ledger or a ledger without that file is not evidence that the copy is unchanged; the warning names the kept file without claiming it contains edits.Type of Change
Evidence
npx tsc --noEmitpassesnpm run lintpassesnpx vitest run, 363 files, 6815 passed, 1 skippedReview correction at
4d192c4c:ENOENT: cleanup deleted the editedretired.mdinpull, full uninstall anduninstall --agent codex.npx vitest run src/__tests__/codex-legacy-rules.test.ts src/__tests__/uninstall.test.tspasses: 2 files, 113 tests. It covers missing, empty and unrelated delivery records, plus removal of a recorded, unchanged copy.npx tsc --noEmit,npm run lint,npm run buildandgit diff --checkpass.New tests, each red before its change:
Real CLI (
npm run build,node dist/index.jsthrough ateamaishim), with a sandboxHOMEandCODEX_HOME, local bare team repos andcodex-cli 0.159.2. The project team has a rule (PELICAN-42), culture (BADGER-8) andclaudemd/(HERON-7); the user-scope team a rule (WREN-5). The committed projectAGENTS.mdholds the owners'OTTER-3. Codex is asked for every codeword without reading files.pull, project scope.codex/rules/sbx-rule.mdgit statusclean;hooks.jsonhasSessionStartandSubagentStartwithadditionalContextLimit: 0codex execin the projectNONEOTTER-3 BADGER-8 HERON-7 PELICAN-42pull, user scope~/.codex/rules/~/.codex/AGENTS.md; no~/AGENTS.md, no~/.codex/rulescodex execoutside any projectNONEWREN-5codex execin the project, both scopesgit statusstill cleandoctor✔ Rules delivered to codex✔ Team rules are inlined in Codex AGENTS.md(user),✔ Project rules and instructions reach codex whole through its session hooksHook behaviour on Codex itself (over 2,500 tokens, compaction, resume, a fresh subagent, an unapproved hook): #938.
Related Issues
Closes #938. Part of #946 (rules) and #945 (instruction blocks).
Notes for Reviewers
additionalContextLimitand theSubagentStartentry are part of Codex's hook trust hash. The public Codex asks each member once to approve the changed teamai hooks; until then it gets no project rules, with no warning.doctorprints the trust reminder.AGENTS.md, which Codex reads. The hook leaves those out, so Codex gets each block once.toolPaths. A Codex-family entry needsuserScope.claudemd; a top-levelclaudemdwould put the blocks back in the projectAGENTS.md. doctor names an entry that lacks it.codex-internalandtcodex, covered by unit tests only.Post-merge review corrections
PR #940 was merged at 12:26 UTC on October 1 while these corrections were being validated. They are not part of its merged head,
4d192c4c.A read-only adversarial subagent (Sol 6.1 xhigh) used the workflow's Codex CLI prompt against main (
b2d3598b...4d192c4c). It confirmed the three P2s in the latest review and found one additional P2: deduplication against a projectAGENTS.mdshadowed byAGENTS.override.md.The follow-up commit
537859a8, based on main85ff72c7, fixes all four: legacy cleanup follows recorded tool roots and publishers' local names (also tombstoned rules), doctor requires both start hooks, and project deduplication reads the active instructions file. The fixes are published separately in #947.Validation at
537859a8: 190 tests acrosscodex-legacy-rules,uninstall,doctorandcodex-hook-rules;npx tsc --noEmit,npm run lint,npm run buildandgit diff --checkpass. The prior real-CLI evidence above is retained; E2E was not rerun for these fixes, as requested.Merge danger
Two-way door: reverting brings back the old copies on the next pull, and the only deletion is the unedited
.codex/rules/*.mdcopies, which teamai can regenerate. Blast radius: Codex-family members.