.windsurfrules file and the newer .windsurf/rules/ directory of scoped Markdown rules. This guide covers both — the formats, the four activation modes, the character limits that bite, and what the fresh Devin Desktop rebrand changes.May 24, 2026 · 10 min read · by Harish Ganapathi
.windsurfrules file and the newer .windsurf/rules/ directory of scoped Markdown rules. This guide covers both — the formats, the four activation modes, the character limits that bite, and what the fresh Devin Desktop rebrand changes.Updated June 2026 — the rebrand
On 2 June 2026, Cognition rebranded Windsurf to Devin Desktop, and windsurf.com now redirects to devin.ai. The Cascade agent is being folded into Devin Local. Your rules don’t break: .windsurfrules and .windsurf/rules/ are still read, but current builds prefer .devin/rules/going forward. We keep the “Windsurf” name throughout because that’s still what everyone searches for — just know the product on your machine may now say Devin.
Key takeaways
.windsurfrules at the workspace root, and the modern .windsurf/rules/*.md directory (now .devin/rules/ preferred).trigger frontmatter field: Always On, Manual, Model Decision, and Glob./-invoked prompt templates.Windsurf rules are persistent instructions injected into Cascade’s context so the agent codes the way your project expects — your stack, your patterns, your forbidden moves. Without them, Cascade re-derives your conventions from whatever happens to be open and gets them wrong often enough to matter. With them, “always use our error wrapper” or “never edit generated files” becomes a standing order.
Like Cursor, Windsurf has two generations of the feature. Knowing which is which — and which limits apply to each — is the whole game.
The original mechanism is a single .windsurfrulesfile at the workspace root: free-form Markdown, no frontmatter, applied to every Cascade conversation in that workspace. It’s simple, but everything in it is always on, with no way to scope a rule to one task or one file type. As it grows, it starts contradicting itself.
# Workspace rules
- TypeScript strict mode. No `any`, no unguarded `as` casts.
- Functions under 50 lines, files under 800.
- Use our internal `Result<T, E>` wrapper for fallible calls.
- Don't run `pnpm install` or migrations without asking first.The modern system is a directory of individual rule files. Historically this was .windsurf/rules/; current builds prefer .devin/rules/ after the rebrand, with .windsurf/rules/ kept as a fallback. Each file is plain Markdown with a small frontmatter block, and — crucially — each one can carry its own activation mode, so you stop paying for every rule on every turn.
| System | Location | Status |
|---|---|---|
| Legacy single file | .windsurfrules (workspace root) | Still read; always-on, no scoping |
| Rules directory (preferred) | .devin/rules/*.md | Current; per-file activation modes |
| Rules directory (fallback) | .windsurf/rules/*.md | Still read for backward compatibility |
| Global rules | ~/.codeium/windsurf/memories/global_rules.md | Applies across every workspace |
A directory rule sets its behavior with a single trigger field in frontmatter. There are four modes, and choosing the right one is mostly how you stay under the character limits (more on that next):
| Mode | When it loads | trigger value |
|---|---|---|
| Always On | Every Cascade conversation | always_on |
| Manual | Only when you @-mention the rule | manual |
| Model Decision | When Cascade judges it relevant (from the description) | model_decision |
| Glob | When an edited file matches the pattern | glob |
A directory rule with frontmatter looks like this:
---
trigger: glob
globs: ["src/**/*.ts", "src/**/*.tsx"]
description: TypeScript service conventions for the API layer
---
- Use our internal `Result<T, E>` wrapper for fallible calls.
- Service names are snake_case; file names match the export.
- Never throw across a module boundary — return a typed error instead.The pattern mirrors Cursor closely: always_on is the global on-switch, model_decision leans on the description to decide relevance, and glob attaches the rule when a matching file is touched. Reach for manualwhen a rule is heavy and only occasionally needed. If you’re weighing the two editors themselves, see our full Windsurf vs Cursor comparison.
This is the part that surprises people coming from Cursor: Windsurf enforces hard character limits, and it silently drops what doesn’t fit.
~/.codeium/windsurf/memories/global_rules.md and applies to every workspace.When you blow past the global cap, Windsurf’s official tip is notto cram more in — it’s to change how rules activate. Switch the less-critical ones from always_on to model_decision or globso they only enter the context when they’re actually relevant. The always-on budget is precious; spend it only on rules that must apply to every single turn.
Sizing tip
Treat always_onas your scarce resource. A short always-on rule that says “follow the conventions in the matching glob rules” plus several scoped glob rules will almost always beat one giant always-on file that overflows. Overflow doesn’t error loudly — it just quietly stops being honored.
Windsurf has three related mechanisms that are easy to conflate. They solve different problems:
| Mechanism | What it is | Best for |
|---|---|---|
| Rules | Static instructions you write and commit | Durable conventions, shared with the team |
| Cascade Memories | Auto-generated, local context from sessions | Cutting repeated re-explaining, just for you |
| Workflows | /-invoked prompt templates | Repeatable multi-step procedures on demand |
Memoriesare auto-generated and stored locally — Cascade records context from a session so you stop re-explaining yourself, but a teammate doesn’t inherit yours. Workflows are Markdown prompt templates in .windsurf/workflows/*.md (also a 12,000-character limit), invoked with /[name] — think of them as saved procedures rather than standing rules. For anything you want the whole team to share and keep in version control, reach for Rules or a portable AGENTS.md, not memories.
If you’ve set up Cursor rules, Windsurf will feel familiar — the two have converged on nearly the same model:
| Windsurf | Cursor | |
|---|---|---|
| Legacy file | .windsurfrules | .cursorrules |
| Directory | .windsurf/rules/*.md | .cursor/rules/*.mdc |
| Activation | trigger field (4 modes) | 3 fields → 4 modes |
| Character limit | 6k global / 12k per file | None (soft ~500-line guidance) |
Both moved from a single root file to a scoped directory, and both offer parallel trigger modes (always-on, manual, model-decision, and glob/path). The defining difference is enforcement: Windsurf imposes hard character limitsthat Cursor doesn’t, which is exactly why Windsurf’s docs push you toward scoped activation modes more aggressively. Cursor uses .mdc with three frontmatter fields; Windsurf uses plain .md with one trigger field.
The 2 June 2026 rebrand is a naming and product shift, not a rules-format break. Here’s the practical migration picture:
.windsurfrules still works. The legacy root file is read exactly as before — no action required..devin/rules/ is now preferred. New builds look here first; .windsurf/rules/ remains a fallback. For a new project, author in .devin/rules/.Migration note
If you maintain rules for a team, the lowest-friction move is to keep your existing .windsurf/rules/ for now and add .devin/rules/when you next touch the repo. Don’t break working setups chasing a rename — both paths resolve, and the format inside the files didn’t change.
Here’s the catch most rules guides skip: almost nobody uses only Windsurf. The moment you also run Cursor, Claude Code, or Copilot, the same conventions you just encoded in .windsurf/rules/ have to be re-encoded in .cursor/rules, CLAUDE.md, and copilot-instructions.md— and then kept in sync forever as each tool’s format drifts (the Devin rebrand is a fresh reminder of how often that happens).
One portability lever is AGENTS.md, the plain-Markdown standard a growing list of agents read directly — useful as a shared baseline even though Windsurf still wants its own trigger modes and limits for fine-grained control. The other is to keep a single canonical library and compile to every format. Skillwright does the latter: author your rules once, then deploy them to Windsurf, Cursor, Claude Code, and Copilot — including the per-tool quirks like Windsurf’s character limits. See how to manage AI coding rules across tools for the full picture, or grab ready-made rule templates to start.
Windsurf enforces two hard limits. The global rules file (~/.codeium/windsurf/memories/global_rules.md) caps at 6,000 characters. Each workspace rule file caps at 12,000 characters. If you hit the global limit, the official fix is to switch less-critical rules from always_on to model_decision or glob so they don't all count against the budget at once.
Both are read. Current builds prefer .devin/rules/ following the June 2026 rebrand to Devin Desktop, with .windsurf/rules/ kept as a fallback. The legacy single file .windsurfrules at the workspace root is also still read. For new projects, author in .devin/rules/; for existing ones, .windsurf/rules/ keeps working.
Rules are static instructions you write and commit to version control. Cascade memories are auto-generated and local — the agent records context from a session so it stops re-asking, but memories aren't shared with teammates and aren't a place to put deliberate conventions. For durable team knowledge, use Rules (or AGENTS.md), not memories.
As of 2 June 2026, Cognition rebranded Windsurf to Devin Desktop, and windsurf.com now redirects to devin.ai. The Cascade agent is being folded into Devin Local. The rules system is unchanged in substance — .windsurfrules and .windsurf/rules/ still work — but new builds prefer .devin/rules/. Most people still search and say Windsurf, which is why this guide keeps the name.
They're close cousins: both started as a single root file, both moved to a scoped directory of Markdown rules, and both have parallel activation modes (always-on, manual, model-decision, and glob/path-based). The big difference is that Windsurf enforces hard character limits (6,000 global / 12,000 per workspace file) that Cursor doesn't, and Cursor uses .mdc with three frontmatter fields where Windsurf uses .md with a single trigger field.