Point feedmill's AGENTS.md at more instruction files
feedmill’s AGENTS.md started tight — the UTC rule, the rate-limit rule — but it’s filling up. Every feed source has its own shape: the Atom parser tolerates a missing updated element one way, the JSON-feed parser handles date_published another, and there’s a page of hard-won notes about which upstreams lie about their encoding. You’ve written all of that down once, in docs/feed-formats.md, and you don’t want to paste it into AGENTS.md — it’s three screens long and it would bury the two rules that actually need to be read on every turn.
So you do the thing your fingers already know how to do. You drop a reference into AGENTS.md:
## Feed parsing
See @docs/feed-formats.md for per-source conventions.If you’ve come from Codex or Claude Code, that @path is muscle memory — both of them expand an @-prefixed path inline, pulling the referenced file into context automatically. So you write the rule, ask for a parser change, and watch the agent get the per-source detail wrong anyway:
> add handling for the new "linkblog" feed — its conventions are in the docs
• Read AGENTS.md, internal/fetch/atom.go (2 files)
I don't see a linkblog format described. AGENTS.md mentions a docs/feed-formats.md but I haven't read it. Want me to open it?The agent read AGENTS.md, saw the literal text @docs/feed-formats.md, and treated it as exactly that — literal text. It did not go open the file. OpenCode does not parse @path imports. That @ syntax has no special meaning inside AGENTS.md; the reference sits there as a string the model can read but the tool never acts on. Codex and Claude Code expand it; OpenCode doesn’t, and a habit that’s invisible everywhere else fails silently here — the rule looks wired up, and only a wrong answer tells you it wasn’t.
Wire the file in through instructions, not @
Section titled “Wire the file in through instructions, not @”The right place to list extra rule sources isn’t AGENTS.md at all — it’s the instructions field in opencode.json. It takes an array of paths, and OpenCode loads every one of them into the rules layer alongside AGENTS.md on every turn:
{ "$schema": "https://opencode.ai/config.json", "instructions": ["docs/feed-formats.md"]}That’s the whole fix. AGENTS.md stays the lean two-rule file it should be; the long per-source reference lives in its own doc where it’s easy to read and edit; and opencode.json is the seam that joins them. Now re-run the same task and the detail is there before you ask:
> add handling for the new "linkblog" feed — its conventions are in the docs
• Read AGENTS.md, docs/feed-formats.md, internal/fetch/atom.go (3 files)
Per docs/feed-formats.md, linkblog feeds are JSON-feed with a non-standard date field and declare UTF-8 but sometimes ship Latin-1. I'll decode defensively and parse the timestamp to UTC.
⏵ Edit internal/fetch/linkblog.goIt read docs/feed-formats.md on its own this time — not because you mentioned it in the prompt, but because instructions pulls it into the rules layer the same way AGENTS.md is pulled. The conventions are in force from the first message of every session, exactly like the rules you wrote inline, just kept in a file of their own.
One glob beats a growing list
Section titled “One glob beats a growing list”The instructions field accepts glob patterns, not only literal paths — which matters the moment you have more than one extra source. feedmill is heading toward a docs/feeds/ directory with a file per format family: atom.md, json.md, rss.md. Rather than naming each one and editing opencode.json every time you add a feed type, match them all:
{ "$schema": "https://opencode.ai/config.json", "instructions": ["docs/feeds/*.md"]}A new docs/feeds/microformats.md is now picked up automatically — write the doc, no config edit. This is the same trick monorepos use to gather a packages/*/AGENTS.md from every sub-package in one line. The glob is the maintainable form; reach for it whenever the list would otherwise grow.
The instructions field even reaches past your own repo: an entry can be a remote URL, and OpenCode fetches it into the rules layer alongside the local files — handy for a shared house style you keep in one place and point every project at. Remote fetches carry a 5-second timeout, so keep anything load-bearing local and treat the remote pull as a convenience, not a dependency.
When you genuinely can’t pre-list it
Section titled “When you genuinely can’t pre-list it”instructions is the answer when you know up front which files carry the rules. Sometimes you don’t — the relevant doc depends on which feed source the task touches, and pre-loading all of them on every turn would just burn context. For that case the fallback is plain prose: tell the agent in AGENTS.md to go read the file when it’s relevant, in ordinary language rather than @ syntax.
## Feed parsing
When adding or changing a feed parser, read the matching file underdocs/feeds/ first (e.g. docs/feeds/json.md for JSON feeds).That instruction the agent does act on, because it’s a directive it understands — “read this file when X” — not an import directive it’s expected to expand. The difference is the whole lesson: OpenCode won’t resolve a path for you, but it will follow an instruction to go read one. So either list the file in instructions and have it loaded for you, or write the prose and have the agent fetch it on demand. What never works is the middle thing — an @path that looks like both and is neither.
Your rules now span a clean AGENTS.md plus a set of focused docs, all loaded on every turn through one config field. That’s the rules layer fully built. The next lever isn’t what the agent knows — it’s how hard it thinks and which model it spends on a given task, where OpenCode’s bring-your-own-model spread really separates it from the single-vendor tools. Next: providers and models.