Agent Skills & Context

Why "which file should I follow?" has no universal answer, how to prove which files your coding agent actually loads, and how to serve one source of truth to every harness on your team.

Slide 1 of 26 — Title

Tutorial

Agent Skills & Context

Stop re-explaining your project every session.

JC Diamante

jcdiamante.com

Presenter note: Set the frame in one sentence: by the end of this you will never again guess which file your AI actually reads — you will be able to prove it in under a minute, on any tool. Ask for a show of hands: who uses Claude Code, who uses OpenCode, who uses Cursor or Copilot. Remember the split, you will call back to it on slide 5.

Slide 2 of 26 — The question

The question behind this talk

"Our project rules live in a skill file and a docs file. Which one does my coding agent actually read?"

— Asked on every team that adopts an AI coding tool

Presenter note: Read it out loud, then ask who has wondered the same thing. Nearly every hand should go up. This is the whole reason the talk exists, and it is a good question asked in good faith. The reason it is hard is not that the person is confused — it is that the honest answer is "it depends," and nobody ever explains what it depends on. We are going to make that dependency explicit. Do not answer it yet. We answer it on slide 24.

Slide 3 of 26 — No universal answer

There is no

universal answer.

It depends who is reading.

Presenter note: Land the pause here. Most people expect the answer to be a filename. It is not a filename — it is a lookup that depends on your tool. That reframe is the single most useful thing in this talk.

Slide 4 of 26 — The harness decides

The core idea

Your repo does not decide

what the agent reads.

The harness does.

Presenter note: Define "harness" plainly: the program wrapping the model — Claude Code, OpenCode, Cursor, Copilot, Codex. The model does not go looking for files. The harness reads specific paths off disk and pastes them into the prompt before the model ever sees your message. So the question "is this the right file?" is really "does my harness read this path?" That is a documented, checkable fact, not an opinion.

Slide 5 of 26 — Two harnesses

Same repo, two readers

Two harnesses. Two contracts.

Claude Code — Reads these paths

CLAUDE.md

.claude/CLAUDE.md

CLAUDE.local.md

~/.claude/CLAUDE.md

.claude/skills/<name>/SKILL.md

OpenCode — Reads these paths

AGENTS.md

~/.config/opencode/AGENTS.md

.opencode/skills/<name>/SKILL.md

.claude/skills/<name>/SKILL.md

.agents/skills/<name>/SKILL.md

"Claude Code reads CLAUDE.md, not AGENTS.md." — code.claude.com/docs/en/memory

Presenter note: Point at the footnote — that is a direct quote from Anthropic's own docs, not my opinion. Then point at the overlap: OpenCode searches SIX skill directories and two of them belong to other tools. It reads .claude/skills and .agents/skills on purpose. That asymmetry is the hinge of the whole talk: OpenCode is permissive about where skills live, Claude Code is strict about the memory filename. Note the OpenCode list is truncated for the screen — it also checks the two global equivalents under the home directory.

Slide 6 of 26 — Different reader

Same repo.

Same skills.

Different reader.

So "correct" is a property of your tool, not your file.

Presenter note: Make this concrete: two people clone the same repository, one gets full project context and one gets nothing, and neither of them did anything wrong. This is why the original question feels unanswerable in a team chat — the asker and the answerer are often on different tools and do not realize it.

Slide 7 of 26 — Two layers

The mental model

Context has

two layers.

Almost every mistake here is putting something in the wrong one.

Presenter note: Transition beat. Once people accept that the harness decides WHERE, the next question is WHAT goes in each file. That is layers.

Slide 8 of 26 — Always on / on demand

The mental model

Always on, or on demand.

Layer 1: Always on

CLAUDE.md, AGENTS.md

Keep it under 200 lines. Facts only.

Every session. Every token.

Layer 2: On demand

SKILL.md

Procedures, checklists, long reference. Size is nearly free.

Only when the description matches.

Presenter note: Layer 1 is billed on every single message you send, forever. That is why Anthropic's docs put a 200-line target on it and why a bloated CLAUDE.md actually makes the model follow you LESS reliably — more instructions, more dilution. Layer 2 is the opposite: the body is not loaded until the agent decides it is relevant, so a 400-line skill costs you almost nothing until the moment you need it. Quote the docs: a skill body "loads only when it's used, so long reference material costs almost nothing until you need it."

Slide 9 of 26 — Facts vs procedures

The sorting rule

Facts go up.

Procedures go down.

Move it to a skill "when a section of CLAUDE.md has grown into a procedure rather than a fact." — Claude Code docs

Presenter note: Give examples out loud. Facts: the package manager is pnpm, the import alias is Z/, tests live here. Procedures: how to cut a release, how to add a collection, the seven-step image pipeline. If it has numbered steps, it is a skill. If it fits on one line and is true all the time, it belongs in the memory file. This one rule fixes most bloated CLAUDE.md files in the room.

Slide 10 of 26 — SKILL.md anatomy

Layer 2

The whole format.

.agents/skills/normalize-webp-images/SKILL.md

--- name: normalize-webp-images description: Convert, verify, and audit local PNG and JPEG content imagery as WebP with Sharp. Use whenever an agent adds, copies, downloads, replaces, or materially edits raster content under public/assets. --- # Normalize WebP Images 1. Run pnpm assets:webp:check to find unconverted rasters. 2. ...

Only two fields are required: name and description.

name must be lowercase and match the folder name.

Everything below the frontmatter is just markdown.

Presenter note: Deflate the intimidation here. People think skills are a framework. They are a folder with a markdown file in it. The frontmatter is two fields. That is the entire specification. You can write your first one in ninety seconds. Mention the folder-name rule specifically — a mismatched name is the second most common reason a skill silently never loads.

Slide 11 of 26 — Description = trigger

The one thing to get right

The description is the trigger.

Weak

Frontend conventions for this repo.

Describes what it is. Never fires.

Real

Use when editing files under src/components/ or src/app/. Covers the Tailwind version and where its config lives, which animation library to import, and the image component rules.

Describes when to use it. Fires reliably.

Write the conditions, not the summary.

Presenter note: This is the highest-leverage slide in the deck. The description is the ONLY part of a skill the agent sees before deciding to load it — it sits in the tool listing next to every other skill. If it reads like a table of contents entry, it never gets picked. If it names the paths, the file types, and the trigger verbs, it gets picked every time. Tell them: write the description last, after the body, and write it as "Use when…".

Slide 12 of 26 — docs/CONTEXT.md

Back to the question

docs/CONTEXT.md

is a third thing.

Nothing loads a doc unless something points at it.

Presenter note: Here is where we disarm half the original question. docs/CONTEXT.md is not a harness path. No tool scans for it. It is a normal document — which means it only enters the agent's context if your AGENTS.md links to it, or a skill routes to it, or the agent happens to open it. That is not a flaw; an index that the memory file points to is a perfectly good design, and it keeps the always-on layer small. But it is a POINTER, not a loaded file, and it is usually an index rather than the rules themselves. Say plainly: if you edit docs/CONTEXT.md and nothing points at it, you have written a document for humans, not for the agent.

Slide 13 of 26 — Three moves

The transferable part

Do not guess which file. Prove it.

1. Read the vendor docs — Every harness publishes its exact search paths.

2. Ask the harness — It will tell you what it loaded this session.

3. Run the canary test — Works on any tool, including ones that document nothing.

Presenter note: This is the part they take home. Everything before now was about Claude Code and OpenCode specifically; these three moves work on a tool that ships next year. Emphasise that move 3 is the fallback that never fails — it needs no docs and no vendor cooperation.

Slide 14 of 26 — Move 1 — the docs

Move 1

Read the vendor docs. They publish the paths.

code.claude.com/docs/en/memory — Load order, precedence, the 200-line target, the AGENTS.md workaround

opencode.ai/docs/skills — All six skill search directories, frontmatter rules

agents.md — The cross-tool standard and who supports it

60,000+: repos using AGENTS.md — Codex, Cursor, Copilot, Gemini CLI, Zed, Windsurf, Aider, goose, Jules, Amp…

Presenter note: The search that works is "<tool name> skills directory" or "<tool name> instructions file precedence" — not "how to give AI project context," which returns blog spam. Then point at the stat: this is why AGENTS.md is the right canonical filename to standardise on even if your personal tool wants a different name. You are betting on the format with twenty-plus implementations, not the one with one.

Slide 15 of 26 — Move 2 — ask it

Move 2

Ask the harness what it loaded.

Claude Code

> /context

Memory files

CLAUDE.md 1.4k tokens

~/.claude/CLAUDE.md 0.9k tokens

If it is not on this list,

Claude cannot see it.

OpenCode

> what skills are available to you

The agent lists them from its

skill tool description — that list

IS the set it can reach.

Missing skill = wrong directory,

or bad frontmatter.

Presenter note: Do this live if the room has a projector and you have a session open. /context is the single most underused command in Claude Code — it shows you exactly what is in the window and what it cost. Important nuance to say out loud: /memory lists where memory files COULD live, /context shows what actually LOADED. People conflate them and debug the wrong thing.

Slide 16 of 26 — Move 3 — the canary

Move 3 — works on any tool, forever

The canary test.

AGENTS.md (line 1)

If you can read this file, begin your reply with the word CANARY.

Put that line at the top of the file you are unsure about.

Start a brand new session. Compaction and history will lie to you.

Ask it anything at all — "hi" is enough.

Presenter note: This is the hero of the talk. It requires no documentation, no vendor support, and no permission. It works on a closed-source tool your company forced on you. It works on skills too — put the canary in the skill body and then ask a question that should trigger it, which tests your description as well as your path. Stress the "brand new session" point: people test in a session that already had the file loaded an hour ago and get a false pass.

Slide 17 of 26 — Canary result

Move 3

Two outcomes. Both are answers.

Loaded

> hi

CANARY

Hey — what are we working on?

The file is in context.

Not loaded

> hi

Hey — what are we working on?

Wrong path, wrong filename,

or wrong directory.

If it does not echo, it never loaded. That is your answer — on any tool, forever.

Presenter note: Do not skip past the failure case. A failed canary is the good outcome, because it took thirty seconds instead of three weeks of wondering why the agent keeps ignoring your conventions. Tell them the three usual causes in order: filename the harness does not read, directory the harness does not scan, or lowercase skill.md.

Slide 18 of 26 — One truth

The team problem

5 tools.

5 filenames.

1 truth.

Copies drift. Symlinks cannot.

Presenter note: Now scale the problem to a team. Somebody uses Cursor, somebody uses Copilot, somebody uses Claude Code. The naive fix is to copy your conventions into five files. That works for about a week. Then someone edits one of them and now you have five subtly different sets of project rules, and no one knows which is authoritative. Tell the story briefly if you have one — this repo used to maintain a 226-line .github/copilot-instructions.md AND four .github/instructions/*.md files AND .cursor/rules/*.mdc, all by hand.

Slide 19 of 26 — Symlink map

The fix, running in a real repo

Two real files. Seven symlinks.

Canonical, real files:

AGENTS.md

.agents/skills/

Symlinks:

CLAUDE.md → AGENTS.md (Claude Code)

.claude/skills → ../.agents/skills (Claude Code skills)

.cursorrules → AGENTS.md (Cursor)

.windsurfrules → AGENTS.md (Windsurf)

.clinerules → AGENTS.md (Cline)

.github/copilot-instructions.md → ../AGENTS.md (GitHub Copilot)

.kiro/steering/AGENTS.md → ../../AGENTS.md (Kiro)

Edit one file. Every tool on the team sees the change.

Presenter note: This is the real state of the repo you are standing in — you can cat any of these live. Two rows deserve narration. Row 2 is the punchline of slide 5: Claude Code does not scan .agents/skills, so the symlink makes an OpenCode-shaped directory readable by Claude Code with zero duplication. And rows 3 through 6 are increasingly belt-and-braces, because newer Cursor, Windsurf, Copilot and Gemini CLI now read root AGENTS.md directly — those links exist for older installs. Kiro is the exception: it has no direct-read path, it auto-loads any .md in .kiro/steering/, so a file has to exist there.

Slide 20 of 26 — The commands

The fix

This is the entire implementation.

bash

# one canonical file, one canonical dir

ln -s AGENTS.md CLAUDE.md

mkdir -p .claude

ln -s ../.agents/skills .claude/skills

git add CLAUDE.md .claude/skills

# stored as mode 120000 — survives a clone

Git stores symlinks natively. Your teammate clones and it already works.

Presenter note: The mode 120000 detail matters more than it sounds. Git does not store a copy of the target — it stores the link itself as a nine-byte blob. So this is not a local dev convenience, it ships. Anthropic's own docs recommend exactly this: "A symlink also works if you don't need to add Claude-specific content." If you DO need Claude-specific rules on top, use an @AGENTS.md import at the top of a real CLAUDE.md instead and add your extra lines below it.

Slide 21 of 26 — Gotchas

Three ways this silently fails

The failures that waste your afternoon.

SKILL.md, not skill.md — macOS is case-insensitive and will happily lie to you. Linux and CI will not. Your skill works locally and vanishes in the pipeline.

name: must match the folder — A skill in api-conventions/ that declares name: api_conventions loads on nobody's machine.

Windows symlinks need admin — Use an @AGENTS.md import on line 1 of a real CLAUDE.md instead. Same result, no privileges.

Presenter note: Number one is worth dwelling on because it is invisible on the machine where you write it. If your team is mixed macOS and Linux, or you run any CI that touches skills, always type the uppercase filename. Ask the room: how many people are on macOS? Then tell them their filesystem has been covering for them.

Slide 22 of 26 — The payoff

Why any of this is worth doing

The prompt you stop typing.

Every session, before

We use pnpm, not npm. Tailwind v4, no config file. Import through the path alias, never relative paths. Use the motion library, not framer-motion. Always use the framework image component. Run the data tests after touching content files. Update the CHANGELOG…

Typed again tomorrow. And the day after.

Every session, after

Add a filter to the projects grid.

The conventions were already in the room.

Setup cost: one afternoon. Paid back inside a week.

Presenter note: This is the ROI slide — say the number plainly. It is not about elegance, it is about the fifteen lines of boilerplate you retype every morning and the fact that you forget three of them when you are tired, and then review catches it. The system does not get tired. Also: this is what makes an agent useful to a NEW teammate on day one, which is the same value proposition as a good README.

Slide 23 of 26 — Start with one

Do this today

Start with one. Not with a system.

1. Write AGENTS.md — Or run /init and edit what it guesses. Facts only. Under 200 lines.

2. Move one repeated prompt into a SKILL.md — The instruction you pasted twice this week. Description starts with "Use when…".

3. Symlink it for your teammate's tool — Then run the canary and confirm both of you are actually reading it.

Presenter note: Kill the perfectionism here. Nobody should leave this room and start designing a context manifest schema. The order matters: one file, then one skill, then portability. Each step pays for itself before the next one is needed. Point at this repo: ten skills now, but it started as one file, and it still has no context manifest — the gap on slide 24 is real and it is fine.

Slide 24 of 26 — The answer

Back to where we started

So — are those the right files?

<your-skill>/SKILL.md: Yes — with two checks — Right idea, right layer. Confirm the filename is uppercase, and confirm your harness actually scans that directory — Claude Code will not read .agents/skills without the symlink.

docs/CONTEXT.md: Only if something points at it — No harness scans for it. It is an index that your AGENTS.md links to, not a file the agent loads on its own — and it is usually generated, so do not hand-edit it.

How you know: Run /context. Not vibes. — Thirty seconds, and you never have to ask this question again.

Presenter note: Close the loop deliberately — go back to slide 2 if you can, so the callback is visible. Give the person credit: they were reading the right kind of file, in the right layer. The uncertainty was never their fault, it was that nobody had made the harness dependency explicit. That is the whole talk in one sentence, and it is the sentence to end on before questions.

Slide 25 of 26 — Closing quote

"Your agent is not ignoring your conventions. It never read them."

Presenter note: Hold the silence here for a beat before the last slide. This is the line to leave the room with, because it reframes every frustration people have had with these tools. Most developers assume the model is being careless or forgetful. Usually the file simply was not in the context window, and that is a thing you can check in thirty seconds rather than a thing you have to feel bad about.

Slide 26 of 26 — Thanks

Thank you !! Let's Connect ✨

JC Diamante — Full Stack Engineer

GitHub: @Zeraphim (https://github.com/Zeraphim)

LinkedIn: /in/jcdiamante (https://www.linkedin.com/in/jcdiamante/)

Instagram: @thatzeraphim (https://www.instagram.com/thatzeraphim/)

ORCID: 0009-0002-6594-956X (https://orcid.org/0009-0002-6594-956X)

YouTube: @thatzeraphim (https://www.youtube.com/channel/UCG1exqSNKgEniM-3XSLcS2w)

Goodreads: jc-diamante (https://www.goodreads.com/user/show/169152072-jc-diamante)

Presenter note: Open the floor. The two questions you will get: "how big should AGENTS.md be" — under 200 lines, and if it is bigger the excess is probably a skill. And "do I need MCP for this" — no, this is all plain files on disk, which is exactly why it is worth doing first. The slides live at jcdiamante.com/resources/agent-skills-and-context if anyone wants to walk through the canary test later.

01 / 26