Build1 publisher3 min readPublished
The globs line decides whether a Cursor rule ever reaches your route handler
A dev.to walkthrough splits one repo-wide Cursor rule into three scoped .mdc files for a Next.js App Router repo. The two path-scoped rules overlap on app/**, and a project that keeps routes under src/ matches neither.
The Engineer · Build desk
What happened
- A dev.to walkthrough replaces one repo-wide Cursor rule with three .mdc files under .cursor/rules: app-conventions for route and component code, server-actions for mutations, and security-boundaries.
- The security rule is deliberately broader than the other two, on the grounds that a secret or authorization mistake can appear in a route, a library or a component boundary.
- A note in the tutorial tells readers to keep the frontmatter keys exactly as their Cursor version expects, naming description, globs and alwaysApply as the useful minimum.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
- cost The sixteen combined instruction lines land on the route and action files the split was meant to keep uncluttered, and the lighter context goes to components/ and lib/, where a mutation bug is less likely to start.
- constraint Scoping is a string match on a path, so a directory move to src/ makes a correct rule stop attaching, and the glob pattern becomes something a reviewer has to check alongside the code.
- contradiction The case for splitting rests on the tutorial's assertion that a repo-wide rule gets ignored, and no compliance measurement is offered, so a team adopting this is buying a config behaviour and taking the attention claim on trust.
Both path-scoped rules match the same files. app-conventions.mdc declares `globs: "app/**/*.{ts,tsx},components/**/*.{ts,tsx}"` with `alwaysApply: false` [3]. server-actions.mdc declares `globs: "app/**/*.{ts,tsx},lib/**/*.{ts,tsx}"` [4]. In the sample layout, the page, the actions file and the route handler all sit under app/ [13]. Editing app/settings/actions.ts pulls both bodies, and each body is eight bullet lines, so sixteen instruction lines attach to one file [16].
Files under components/ and lib/ each match one rule [17]. The split therefore trims the most context from the directories where the fewest expensive mistakes happen. The tutorial is clear about what it is trying to buy: "The goal is not to make an agent autonomous. The goal is to put the right reminder beside the code where a mistake would be expensive" [6]. I think the split is the right default, and I would give the two path rules disjoint globs before committing them.
Be literal about attachment. With `alwaysApply: false`, a rule body enters context when the path of the edited file matches one of the patterns in `globs` [3]. By its own test for the design, "Editing components/ should show component conventions; editing a documentation file should not" [7]. Move the routes to src/app and the pattern has to become src/app/**/*.{ts,tsx} [8]. That maintenance duty is written into the rule text as a bullet instructing the agent to update the globs when the project uses src/ [10]. An instruction file that asks the agent to keep the instruction file's frontmatter current is an unusual division of labour.
The frontmatter is coupled to the editor version, and no version number appears. The note tells readers to keep the keys exactly as their Cursor version expects and calls description, globs and alwaysApply the useful minimum for a scoped project rule [9].
The stated reason for splitting is that a rule applying to every file is "surprisingly easy to ignore" [1]. That is an assertion about agent attention. The walkthrough does not test it [18]. The part that transfers to your repo without argument is the file format and the path matching [3][9].
The rule text is well made where it matters. The convention rule says to prefer Server Components by default and to add `"use client"` only for hooks, browser APIs or interactive event handlers [10]. The tutorial notes that the limit is deliberate and that the rule does not say "always use Server Components" [19]. The mutation rule opens by treating every Server Action and Route Handler as a public server boundary, then requires validation of form data, JSON, params and search params before use, and authorization checks on the server [11]. The tutorial's reason is direct: "Anyone who can reach the application may attempt to invoke the endpoint, so hiding the button is not an authorization mechanism" [12].
Only the security rule stays broad, because an authorization or secret mistake can happen in a route, a library or a component boundary [5]. The text breaks off inside a mutation example, before that rule's frontmatter is printed [18].
What to watch
- Whether Cursor keeps the description, globs and alwaysApply keys stable across versions; a rename means editing every rule file in .cursor/rules.
- The security rule's actual scope, which the published text stops short of printing: a wide glob or alwaysApply: true behave differently at review time.
- Whether the two path rules get disjoint globs, so a mutation file stops loading the component conventions as well.