.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 manual when a rule is heavy and only occasionally needed.
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.