Repository navigation
[bug] Codex never gets the team rules: session-start hook in project scope, $CODEX_HOME/AGENTS.md in user scope #938
Description
Activity
- added 4 commits that reference this issue
on Sep 30, 2026 The project
AGENTS.mdis read by more tools than CodexInlining team content into the project
AGENTS.mdmakes every other tool that reads that file read it too. Several of those tools already get their own copy of the rules from teamai, in their own format, so they would read every rule twice. Worse, the copy in the block is always on, so apaths:rule loses its scoping in those tools.Checked on 2026-10-01. The test project held an
AGENTS.md(codewordOTTER-3), an always-on team rule (PELICAN-42) and apaths: ["src/**"]team rule (HERON-7). teamai delivered both rules in each tool's own format. Each CLI was asked, without reading any file, which codewords its instructions hold.CLI Reads the project AGENTS.mdIts own copy of the team rules With Codex in the same repo Codex 0.159.2 yes ( OTTER-3)none as intended Claude Code 2.1.285 only when there is no .claude/CLAUDE.md: it reportedOTTER-3without one and not with one.claude/rules/;paths:honored (HERON-7only after readingsrc/app.ts)rules twice, unless the team ships culture or claudemd/, which creates.claude/CLAUDE.mdOpenCode yes ( OTTER-3).opencode/rules/throughinstructions;paths:not honored (HERON-7reported without reading a file)rules twice Cursor yes per its docs: "Cursor supports AGENTS.md in the project root and subdirectories". Not reproduced: the test account hit its usage limit .cursor/rules/*.mdcrules twice GitHub Copilot CLI yes per its docs: it reads AGENTS.mdand "combines their instructions". Not reproduced: the account's model was rejected.github/instructions/*.instructions.mdwithapplyTorules twice User scope is not affected: only Codex reads
$CODEX_HOME/AGENTS.md.The same overlap applies to the culture,
claudemd/and recall blocks, which #945 tracks for every tool.Direction. In project scope, teamai writes nothing for Codex to the shared
AGENTS.md. The channel is in the next comment. #946 covers how the other tools read rules.- changed the title
[-][bug] Team rules never reach Codex: pull copies them into .codex/rules (Codex's command-policy dir) instead of AGENTS.md[/-][+][bug] Team rules never reach Codex: pull copies them into .codex/rules, which Codex never reads[/+]on Oct 1, 2026 Codex channel for team rules: the session-start hook works. Tested on Codex 0.159.2
#946 proposes giving team rules to tools with no rules format through their session-start hook. For Codex, here is how that compares with the other channels:
Channel (project scope) Keeps AGENTS.mdDownside SessionStarthook,additionalContext(recommended)yes needs hook trust, which teamai's existing hooks already need; see the caveats below developer_instructionsin.codex/config.tomlyes ignored in untrusted projects, silently in codex exec; overwrites the member's own value; clashes with a committed.codex/config.tomlblock in AGENTS.md(#940 today)yes Cursor, Copilot, OpenCode, Claude and other tools read it too (comment above) model_instructions_fileyes replaces Codex's base prompt AGENTS.override.mdno hides AGENTS.mdproject_doc_fallback_filenamesn/a only read when there is no AGENTS.mdWhat I ran. Real
codex exec, with an isolatedCODEX_HOMEand a hook that printsadditionalContextholding a codeword. The prompt asked for the codeword without reading files.Case Result small context, hook trusted codeword returned hook not trusted NONE. The hook is skipped with no warning incodex exec. The TUI asks at startup instead~6k tokens, codeword in the middle NONE. Above 2,500 tokens Codex keeps a head/tail preview and spills the rest to a temp filesame, with "additionalContextLimit": 0on the handlercodeword returned resume --lastcodeword returned (it is in the history); the hook fires again with "source":"resume"auto-compaction ( model_auto_compact_token_limit = 12000)"context compacted", then the hook fires with "source":"compact"; codeword returned afterwardsWhat the teamai handler needs (in the existing
teamai hook-dispatch session-startentry):on SessionStart source == resume → add nothing # the history already holds them startup | clear | compact → add the project's rules and blocks # user-scope ones live in $CODEX_HOME/AGENTS.md handler config: additionalContextLimit: 0 # or a value above the team's rules sizeCaveats:
- Re-approval once.
additionalContextLimitis part of the hook's trust hash (hook_hashincodex-rs/hooks/src/engine/discovery.rs). Adding it means each member approves the teamai hook again, one time. Adding a handler insidehook-dispatchdoesn't change the hash. - Subagents. Spawned subagents fire
SubagentStart, notSessionStart(core/src/hook_runtime.rs). A forked subagent inherits the history; a fresh one gets no rules unless teamai also registersSubagentStart, which is a new entry and needs approval. Read from the code here; fix(rules): give Codex the team rules: session hooks in a project, its own AGENTS.md in user scope #940 then ran it with a fresh subagent. - Untrusted hook = no rules, silently.
doctorshould report a teamai hook that Codex has not trusted.
In project scope the hook carries the rules, and, per #945, the culture,
claudemd/and recall blocks; nothing goes to the projectAGENTS.md. In user scope they go to$CODEX_HOME/AGENTS.md, which only Codex reads. #940 keeps the.codex/rulescleanup,doctoranduninstall. Tracking for all tools: #946 (rules) and #945 (instruction blocks).- Re-approval once.
- changed the title
[-][bug] Team rules never reach Codex: pull copies them into .codex/rules, which Codex never reads[/-][+][bug] Team rules never reach Codex: add them through the session-start hook[/+]on Oct 1, 2026 I rewrote this issue with the fix.
- Project scope: Codex gets the team rules, and the culture,
claudemd/and recall blocks, through its session-start hook and aSubagentStartentry. teamai writes nothing to the projectAGENTS.md. - User scope: they go to
$CODEX_HOME/AGENTS.md, which only Codex reads.
The project
AGENTS.mdis also read by Cursor, Copilot, OpenCode and Claude, which would then get every rule twice and lose thepaths:scoping. Codex has no project file that only it reads and that also loads in untrusted projects. The test results are in the comment above.pullanduninstallstill clean up the old.codex/rulescopies. This issue is the Codex part of #946 (rules) and #945 (instruction blocks). #940 implements it and stays a draft until it does.- Project scope: Codex gets the team rules, and the culture,
- changed the title
[-][bug] Team rules never reach Codex: add them through the session-start hook[/-][+][bug] Codex never gets the team rules: session-start hook in project scope, $CODEX_HOME/AGENTS.md in user scope[/+]on Oct 1, 2026 - added a commit that references this issue
on Oct 1, 2026 - added a commit that references this issue
on Oct 1, 2026 - added a commit that references this issue
on Oct 2, 2026 - added a commit that references this issue
on Oct 3, 2026
Part of #946 (rules) and #945 (instruction blocks). This issue is the Codex case.
Problem
pullcopies each team rule to.codex/rules/<name>.md, anddoctorreports✔ Rules delivered to codex. Codex never reads those files. It uses.codex/rules/for command-policy files (*.rules). Asked for a rule's content,codex execanswersNONE. The culture, sharedclaudemd/instructions and recall block never reach Codex either.codex-internalandtcodexhave the same paths. Rules have been broken since 573a54c addedrules: '.codex/rules'.Fix
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;User scope: a file. Only Codex reads
$CODEX_HOME/AGENTS.md. Codex loads it in every session and again after compaction, it needs no hook trust, anddoctorcan compare its bytes.Project scope: the hook. teamai already installs a
teamai hook-dispatch session-startentry in Codex'shooks.json, and it already adds the secrets hint asadditionalContext(#875). The project's rules and blocks become one more handler in that entry, plus aSubagentStartentry. A file does not work here:AGENTS.mdis also read by Cursor, Copilot, OpenCode and Claude, which get the rules in their own format (evidence). It is also the owners' file, and teamai leaves it unchanged ([bug] Team members with different roles overwrite each other's blocks in shared root AGENTS.md #945).developer_instructionsin.codex/config.tomlloads only in trusted projects, and it replaces the member's own value.model_instructions_filereplaces Codex's base prompt.AGENTS.override.mdhidesAGENTS.md.project_doc_fallback_filenamesis ignored when anAGENTS.mdexists.Tested on Codex 0.159.2
A real
codex execwith an isolatedCODEX_HOMEand a hook that returns a codeword (details):NONE, andcodex execprints no warningNONE, because Codex keeps only the start and end of anything over 2,500 tokens"additionalContextLimit": 0resume --lastsource: "resume"source: "compact"; codeword returned afterwardsfork_turns: "none")SubagentStart(run in #940)Expected
.codex/rules, never read~/.codex/rules, never read$CODEX_HOME/AGENTS.mdclaudemd/, recall$CODEX_HOME/AGENTS.mdpaths:Applies to files matching: <globs>line (the same renderer as Hermes'SOUL.md)"additionalContextLimit": 0, so Codex does not cut itSubagentStartentry adds the same project contentAGENTS.md.codex/rulespullanduninstallremove the copies that match what teamai delivered; they keep edited copies and name them, and never touch*.rulesdoctor✔ Rules delivered to codex, a false positivecodex-internal,tcodexskill-data/Members approve the teamai hooks again once.
additionalContextLimitand theSubagentStartentry are part of Codex's trust hash, and both land in the same pull.Acceptance criteria
codex execreturns a team rule and the culture in project scope (from the hook) and in user scope (from$CODEX_HOME/AGENTS.md), from a real-CLI run of the build..codex/rulesor to the projectAGENTS.md.sourceisresume.claudemd/file scoped to another role or project does not reach Codex.pullanduninstallremove unedited.codex/rulescopies, keep edited ones with an English warning, and leavedefault.rulesalone.doctorfails with an actionable English message when a hook entry is missing or lacks the limit, and no longer printsRules delivered to codex.codex-internalandtcodexpass the same tests.skill-data/references are updated.Open
doctordetects that Codex has not trusted the hooks. Codex keepstrusted_hashinconfig.toml, and recomputing that hash in teamai would copy Codex's internal format.codex-internalandtcodexare assumed to match Codex's layout.Non-goals
Reproduction (0.22.0)
A sandbox with its own
HOMEandCODEX_HOME, and a local bare team repo holdingrules/sbx-rule.md= "The team codeword is PELICAN-42."Environment: macOS 27.0, Node.js v24.21.0, teamai 0.22.0 (
origin/maindf940cd), providergit,codex-cli 0.159.2, Claude Code.