Course · Cursor · Rules · .mdc & AGENTS.md
The sharp edge: globbed rules, and the legacy .cursorrules
The sharp edge: globbed rules can be silently skipped
Section titled “The sharp edge: globbed rules can be silently skipped”Here’s the one that surprises people, and it’s worth internalizing before it costs you a debugging session. Quick orientation first: rules are .mdc files in .cursor/rules/ whose frontmatter - alwaysApply, globs, description - controls when they attach. You’d reasonably assume that Apply to Specific Files is deterministic - that a rule with globs: ["src/api/**"] will load whenever an src/api/ file is open in your editor, the way a build tool’s glob is mechanical. It isn’t quite that. (Apply to Specific Files is the current docs’ name for the glob-scoped rule type, as of October 2026; rules documentation; older tutorials call it Auto Attached.)
The behavior reported by the community is that a glob-scoped rule (alwaysApply: false) can fail to load even when you’d expect it to. The precise trigger, as the forum thread clarified, is narrower than “the model ignored it”: from Cursor 2.0 on, a glob rule only attaches when the matching file actually enters the agent’s context - pulled in by an @-mention or a file the agent itself decides to read - not merely by being open in your editor. That’s a behavior change from Cursor 1.x, where having the file open was enough. So you can have a perfectly written api-validation.mdc, scoped to exactly the right files, watch yourself edit a handler in src/api/, and still get hand-rolled if-validation back - because the file was open in the editor but never entered the agent’s working context, so the rule never attached. This is the “glob rules not auto-loaded” friction, and it’s a recurring report on the Cursor forum.
The practical lesson, in budgetcli (the course’s illustrative finance API, whose handlers live under src/api/) or any repo: if a rule is load-bearing - a convention you cannot afford the agent to miss - don’t trust a glob to deliver it. Promote it. A non-negotiable like “API handlers validate with Zod” is safer as an Always Apply rule (alwaysApply: true) or as a line in the root AGENTS.md - the root file’s children are the whole repo, so it is effectively always in force - than as a glob-scoped rule that only attaches if the matching file happens to enter the agent’s context. (Mind the word root: nested AGENTS.md files are not unconditional - per the docs they “will be automatically applied when working with files in that directory or its children”, the directory-scoped cousin of this same trap.) Save Apply to Specific Files for guidance that’s helpful when it fires but not catastrophic when it doesn’t - style preferences, module-local hints - and keep the bugs-you-keep-reintroducing in an always-on layer.
The legacy path: .cursorrules
Section titled “The legacy path: .cursorrules”If you’ve used Cursor for a while, or you’re looking at an older repo, you’ll meet a single .cursorrules file at the project root - the original, pre-.mdc format. It’s a plain file of instructions with no frontmatter and no per-file attachment: one undifferentiated blob, always applied.
Cursor still honors .cursorrules for backward compatibility, so an old repo keeps working. Worth knowing where this status comes from: Cursor’s current rules documentation no longer mentions .cursorrules at all - it’s been dropped from the docs entirely, consistent with “legacy, no longer recommended,” and community reports line up, describing it as deprecated-but-still-working since Project Rules landed in late 2024. So treat the “still honored for backward compatibility” line as the well-understood legacy status, not a sentence you’ll find quoted on the docs page. Either way, it is no longer the recommended path - new work belongs in .cursor/rules/*.mdc (for Cursor-specific power) or AGENTS.md (for portability), both of which give you scoping .cursorrules never had. If you inherit a .cursorrules, the clean migration is to move its always-true lines into AGENTS.md and split anything conditional into scoped .mdc rules.
Where each convention belongs
Section titled “Where each convention belongs”Whatever the repo, the placement logic this chapter leaves you with is the same:
- Flat, portable truths - store timestamps in UTC, keep money in integer cents - belong in
AGENTS.mdat the root, in force on Cursor and on any teammate’s Codex or OpenCode. - Conventions with a moment belong in
.cursor/rules/*.mdcProject Rules, where the frontmatter picks it: always-on (alwaysApply: true), model-judged (the agent reads the rule’sdescriptionand pulls the rule in when the task looks relevant), file-scoped (globs), or pulled in on demand with an@-mention in chat. - Personal habits - “always show me a diff before editing” - belong in User Rules (edited from Customize → Rules, the current docs’ label), which follow you across every repo; org-wide mandates can be pushed as Team Rules from the dashboard with no local file, on Team and Enterprise plans (rules documentation, as of October 2026).
- And the trap to remember: a load-bearing rule hidden behind a glob only attaches when the matching file enters the agent’s context, so anything you cannot afford to miss belongs in an always-on layer instead.
The agent doesn’t get smarter because you wrote rules. It stops having to guess at the project’s conventions every session, because it can read them. Ask for a new handler and the Zod validation and the UTC timestamp are simply there - a mistake you never review, because it never gets made.
Rules decide what the agent knows before it acts. What it’s allowed to do once it acts is a separate dial entirely - and why the sandbox, not allow/deny lists, sets that dial is exactly the next chapter. Next: permissions, auto-run and the sandbox.