Repository navigation
fix(codex): address post-merge delivery review findings - #947
Merged
Merged
Conversation
5 of 9 tasks
|
No findings. The prior Codex cleanup, hook validation, and |
24 of 28 tasks
jeff-r2026
approved these changes
Oct 2, 2026
7 of 8 tasks
SaulMoro
added a commit
to SaulMoro/teamai-cli
that referenced
this pull request
Oct 2, 2026
Carries Tencent#952 (fix/945-member-instruction-targets at 46d7635) rebased onto main, which now holds Tencent#947. Tencent#952 drops the Codex hook's skip for blocks already in the project instructions file, so Tencent#947's AGENTS.override.md variant of that skip and its test go with it.
SaulMoro
added a commit
to SaulMoro/teamai-cli
that referenced
this pull request
Oct 2, 2026
…override.md (Tencent#945) Tencent#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 Tencent#947's skip test, and drops the skip sentence from the unreleased Tencent#938 changelog entry.
This was referenced Oct 2, 2026
jeff-r2026
pushed a commit
that referenced
this pull request
Oct 3, 2026
… 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)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Follow-up to #940, which merged while the latest review corrections were being validated. This fixes the three open review findings and one additional project-context defect found by the adversarial review.
The publisher mapping reuses
localNameFor; relocated cleanup reusesresolveToolRootDir. Both destructive callers retain the same ownership classification. Edited and unverified copies, including tombstones without delivery hashes, stay; Codex's*.rulespolicies stay too. An empty readable override still shadowsAGENTS.md. English/Chinese usage guides, the uninstall skill and changelog match the fixes.Evidence
537859a8, based on main85ff72c7):npx vitest run src/__tests__/codex-legacy-rules.test.ts src/__tests__/uninstall.test.ts src/__tests__/doctor.test.ts src/__tests__/codex-hook-rules.test.tspasses: 4 files, 190 tests. Tests cover unchanged versus edited copies, publisher placement proof, tombstoned delivery hashes, both start events, readable/empty overrides, duplicate suppression and unchanged project files.npx tsc --noEmit,npm run lint,npm run buildandgit diff --checkpass.b2d3598bthrough fix(rules): give Codex the team rules: session hooks in a project, its own AGENTS.md in user scope #940 head4d192c4c, Sol 6.1 xhigh subagent; 0 P1, 4 P2 (three prior, one new), 0 P3. All four are addressed here.Representative real-CLI evidence is retained from #940, before this follow-up. E2E was not rerun for these corrections, as requested. That validation built the CLI and ran
node dist/index.jsthrough ateamaishim with a sandbox HOME/CODEX_HOME, local bare team repos andcodex-cli 0.159.2:pull, thencodex execwithout reading filesOTTER-3, cultureBADGER-8, shared instructionsHERON-7and team rulePELICAN-42pull, thencodex execoutside a project~/.codex/AGENTS.md; no old rules directory; Codex returnsWREN-5codex execin a project with both scopescodex-internalandtcodexhave unit coverage; live coverage remains as documented in #940.Merge Danger
Door: one-way for cleanup.
Cleanup removes only copies proven to match TeamAI's delivery; edited or unverified copies stay. Reverting cannot restore a removed copy whose source was tombstoned. Doctor and hook-context changes can be reverted.
Blast Radius: Codex-family.