Example

Separate discovery from admission in the context pipeline

A file can exist, be discovered and admitted, and never reach the model — see who owns each of the four steps with a temporary fixture tree.

“the model read my AGENTS.md” hides four facts: the file exists, Pi discovered it, something admitted it, and it is in the request the model receives. Each fails on its own and each has a different owner. The excerpts below ran as the Chapter 28 tests against a temporary tree — default loader, no model.

Discovery: a walk up, not a scan down

Starting Pi in repo/src/billing, discovery walks up from the working directory to the agent directory — never sideways or down, so repo/docs/AGENTS.md does not apply to work started in repo/src/billing even though both are in one repository:

started in repo/src/billing
  agent/AGENTS.md              discovered — agent directory
  repo/AGENTS.md               discovered — a parent
  repo/src/billing/AGENTS.md   discovered — working directory
  repo/docs/AGENTS.md          not discovered — a sibling

The test asserts the walk-up rows:

	const loader = new DefaultResourceLoader({ cwd: billing, agentDir });
	await loader.reload();
	const got = names(loader.getAgentsFiles().agentsFiles);

	assert.ok(got.includes("AGENTS.md=user rules"), "the agent directory applies everywhere");
	assert.ok(got.includes("AGENTS.md=repo rules"), "a parent directory is inherited downward");
	assert.ok(!got.some((g) => g.includes("docs rules")), "a sibling directory is never discovered");

Admitted: an override replaces only what is beside it

An AGENTS.override.md replaces the AGENTS.md or CLAUDE.md in the same directory and only that one. It is a sibling replacement, not a global kill switch — the repo-root and agent-directory files survive it. The cited test asserts both halves.

The host owns admission

In an embedded application the files the model sees are whatever the resource loader returns. agentsFilesOverride receives what was found and returns what to use — here the host drops the user file and adds a virtual one:

	const loader = new DefaultResourceLoader({
		cwd: billing,
		agentDir,
		agentsFilesOverride: (current) => ({
			agentsFiles: [
				...current.agentsFiles.filter((f) => !f.content.includes("user rules")), // never admit the user's own file
				{ path: "/virtual/AGENTS.md", content: "policy supplied by the host" },
			],
		}),
	});

Expected outcome

Step Owner Fixture result
Exists whoever wrote the repository all five files are on disk
Discovered Pi’s directory walk agent, repo and billing files; docs never
Admitted Pi’s rules, you, an extension, or the host override replaces only billing’s AGENTS.md; the host swaps the user file for a virtual one
In context the request builder the loader’s list, on every request

The working directory chooses which rules exist, and the default loader caches what it reads until reload(); a custom ResourceLoader decides for itself.

Mechanism and limitations

Documented: configuration.md pins discovery (the agent directory, the working directory and its parents), the accepted names, the local override rule and --no-context-files; sdk.md pins DefaultResourceLoader and agentsFilesOverride (1.0.4). Observed: the three tests of admission.test.ts passed against the real loader in a temporary tree with no model: siblings are never discovered, an override replaces only the file beside it, and a host override both drops and adds files. Proposed: the four-step split and admission as application policy are this book’s framing.

This is not a security boundary: context files load without project trust, so an unfamiliar repository’s AGENTS.md is admitted before anything is approved. If the instructions matter, the host must admit them itself; no model is involved here.

Full source and test .

Understand this example

Copy this prompt into your AI tool. No code runs here.

Apply this example

Copy this prompt into your AI tool. No code runs here.