refactor(agent/agentcontext): fixed-location shallow context discovery#26596
Merged
Conversation
Instruction-file resolution over-injected context: the resolver walked the working directory recursively, matched filenames case-insensitively, and emitted symlinked duplicates. Resolving the repo root produced six instruction sources (AGENTS.md plus its CLAUDE.md and .cursorrules symlinks, a nested site/AGENTS.md and site/CLAUDE.md, and the lower-case docs/reference/api/agents.md API doc) that amounted to one file's worth of guidance. Align with codex, which finds the project root by walking up to .git and reads at most one AGENTS.md per ancestor directory rather than descending into subdirectories: - Recognize instruction files only at a scan root's top level. Skills and .mcp.json keep recursive discovery, since they are a Coder extension with no codex equivalent. - Match instruction basenames case-sensitively, so a lower-case agents.md is not mistaken for an instruction file. - Attribute each resource to its resolved symlink target so CLAUDE.md and .cursorrules symlinked to AGENTS.md collapse into one resource via the existing ID-based dedup instead of shipping identical content multiple times. On resolve failure the original path is kept so the error points at the offending link. Resolving the repo root now yields a single instruction resource.
sreya
approved these changes
Jun 23, 2026
… discovery The resolver previously walked the working directory recursively to depth 8 and matched any nested instruction file, .mcp.json, or skills/ directory. codex never walks the working tree downward: it reads fixed locations and walks up to the project root. Replace the recursive engine with codex-style discovery. - Manager walks up from the working dir to the nearest .git ancestor (a directory, or a worktree/submodule .git file) and feeds the root->cwd chain as separate scan roots. - Resolver inspects only each scan root's top level for instruction files and .mcp.json, and discovers skills from fixed container locations (skills, .agents/skills, .claude/skills, .codex/skills), one skill per immediate subdirectory. The recursive walkDir, skipDirNames, MaxScanDepth, and isSkillsContainer are removed. - Watcher mirrors the same fixed-location set instead of recursively watching every scan root, so it no longer walks node_modules and other large trees. .mcp.json is kept (no codex config.toml support). Resolving the repo root now yields AGENTS.md, .mcp.json, and the .agents/skills and .claude/skills skills, with no nested instruction-file noise.
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
Problem
agent/agentcontextresolved workspace context by walking the working directory recursively (depth 8) and matching files by basename. This over-injected context:docs/reference/api/agents.mdwas treated as an instruction file.CLAUDE.md,.cursorrules->AGENTS.md) shipped as duplicate resources.AGENTS.md(e.g.site/AGENTS.md) were collected from anywhere in the tree.skills/directory anywhere in the tree, and.mcp.jsonfrom any depth.Resolving the repo root produced six instruction sources for what was effectively one file of guidance, plus skills/MCP found by an open-ended walk.
What changed
Replace the recursive scan with fixed-location, shallow discovery. Each scan root is inspected at its top level only: the resolver never descends into subdirectories and never climbs to a parent. Additional directories are added explicitly as sources (HTTP API) or via the
CODER_AGENT_EXP_*_DIRSseeding env vars..mcp.jsonare read only at its top level.skills,.agents/skills,.claude/skills,.codex/skills(one skill per immediate subdir with aSKILL.md), not from arbitraryskills/directories.AGENTS.md/CLAUDE.md/.cursorrules; a lower-caseagents.mdis ignored.CLAUDE.md/.cursorrulescollapse into the singleAGENTS.md.node_modules).walkDir,skipDirNames,MaxScanDepth, andisSkillsContainerare removed.Resolving the repo root now yields
AGENTS.md,.mcp.json, and the.agents/skills/.claude/skillsskills, with no nested instruction-file noise.Behavior change
site/AGENTS.mdis no longer auto-injected when the working dir is the repo root. It loads when the working dir issite/(its top level), or whensite/is added as an explicit source. There is intentionally no walk-up to a.gitproject root: an agent started in a subdirectory does not auto-inherit ancestorAGENTS.md; those directories are added explicitly.Verification & decision log
codex research (confirmed via source). Instruction files: codex walks up to the first
.gitancestor and reads root->cwd, one file per directory, exact-cased names (codex-rs/core/src/agents_md.rs). Skills: fixed roots (.agents/skills,.codex/skills,$CODEX_HOME/skills, ...) with bounded in-root recursion (core-skills/src/loader.rs). MCP:.codex/config.tomlvia walk-up; a project.mcp.jsonis not a runtime source in codex. No resource type triggers an unbounded downward walk.Decisions.
.gitproject root. In Coder the working dir is the scan root and extra directories are added explicitly (HTTP API /CODER_AGENT_EXP_*_DIRS), so the implicit ancestor climb added surprise without benefit (e.g.context add ./siteshould scan./site, not the repo root)..mcp.json(codex usesconfig.toml, intentionally not added)..claude/skillsand.codex/skillsin the container list so the repo's existing.claude/skillsskills are not regressed; skills recurse one level inside a container.Tests.
TestManager_WorkingDirScannedShallow(working dir read at top level; ancestor root and nested subdir both excluded);TestResolver_SkillsOnlyFromFixedContainers,TestResolver_MCPConfigOnlyAtScanRoot,TestResolver_SymlinkedInstructionFilesDeduplicated,TestResolver_InstructionFilesOnlyAtScanRoot,TestResolver_InstructionNamesAreCaseSensitive. Cap tests use multiple scan roots.Local checks.
gofmt,go vet,golangci-lint,go test -race, andmake lint/emdashpass for the package.🤖 Generated by Coder Agents on behalf of @kylecarbs.