Cursor Notepads: Living Architecture Constraints Agents Must Obey

Cursor Notepads: Living Architecture Constraints Agents Must Obey
12 views

This guide covers Cursor Notepads with production-focused examples and trade-offs.

Cursor Notepads are the cheapest architecture enforcement you will ever get an agent to respect. Rules tell the model how to edit; notepads tell it what the system is allowed to become. Without living constraints — bounded contexts, event schemas, forbidden libraries — Agent Mode invents cross-domain coupling that seniors spend the next sprint unwinding. Treat notepads as versioned architecture contracts attached to every agent turn, not sticky notes you forget to open.
⚡ TL;DR: Keep one notepad per bounded context with allowed dependencies, public event shapes, and a hard ban list. Pin notepads into Agent Mode context every session. Diff notepad changes like code. Reject agent plans that violate declared edges. Pair with Cursor Agent Mode CI gates and Cursor rules for AWS CDK so rules + notepads form a closed loop.

Model notepads as architecture contracts — Cursor Notepads

A notepad is not “extra context.” It is a machine-readable contract the agent must cite before touching files.
markdown
# notepad: payments-bounded-context (v14)
## Owns
- packages/@acme/payments/**
- events: PaymentAuthorized, PaymentCaptured, PaymentRefunded

## May depend on
- @acme/identity (read-only userId)
- @acme/ledger (write via LedgerClient only)

## Forbidden
- direct import from @acme/marketing/**
- raw Stripe SDK outside adapters/stripe/
- DynamoDB DocumentClient outside infra/

## Event schema freeze
- PaymentAuthorized.v2: { paymentId, amountMinor, currency, userId }
- ❌ Do not invent PaymentSuccess — use PaymentCaptured
typescript
// scripts/assert-notepad-cited.ts — gate agent plans
export type AgentPlan = {
  notepadIds: string[];
  files: string[];
  newEvents?: string[];
};

const REQUIRED = ["payments-bounded-context", "platform-forbidden-libs"];

export function assertNotepads(plan: AgentPlan) {
  for (const id of REQUIRED) {
    if (!plan.notepadIds.includes(id)) {
      throw new Error(`missing_notepad:${id}`);
    }
  }
  // ❌ Never: agent invents PaymentSuccess
  const banned = (plan.newEvents ?? []).filter((e) =>
    /Success|Failed|Done$/i.test(e) && !/^Payment(Authorized|Captured|Refunded)$/.test(e)
  );
  if (banned.length) throw new Error(`undeclared_events:${banned.join(",")}`);
}
✅ Notepad version bumped in the same PR as the architecture change.
❌ Orphan notepad text that no longer matches CODEOWNERS or package boundaries. See also Claude Projects vs Cursor context hygiene when regulated repos need ignore rules on top of notepads.

Pin notepads into every Agent Mode turn

Agents do not “remember” last week’s architecture chat. Explicitly attach notepads; fail the session opener if they are missing.
bash
# ✅ Session bootstrap (illustrative)
cursor-agent --attach-notepad .cursor/notepads/payments.md \
             --attach-notepad .cursor/notepads/forbidden-libs.md \
             --rule .cursor/rules/bounded-contexts.mdc

# ❌ “The agent already knows our architecture from yesterday”
yaml
# .github/workflows/notepad-drift.yml
name: notepad-drift
on: [pull_request]
jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Notepad ↔ package graph
        run: node scripts/check-notepad-deps.mjs
      - name: Forbidden import lint
        run: node scripts/lint-forbidden-from-notepads.mjs

Diff notepads like code, not docs

Architecture rot starts when notepads become wiki pages. Require CODEOWNERS on .cursor/notepads/** and block merges that expand May depend on without an ADR link.
typescript
// scripts/check-notepad-deps.mjs — excerpt
import { readFileSync } from "node:fs";
import { parseNotepad } from "./notepad-parse.js";

const np = parseNotepad(readFileSync(".cursor/notepads/payments.md", "utf8"));
for (const edge of np.mayDependOn) {
  // ✅ every edge must map to a real package
  if (!existsPackage(edge)) throw new Error(`ghost_dep:${edge}`);
}
for (const ban of np.forbidden) {
  // ❌ agents proposing imports matching ban → CI fail
  assertNoImportsMatching(ban);
}

Closing checklist

✅ Dos
– ✅ One notepad per bounded context with owns / may-depend / forbidden
– ✅ Attach notepads every Agent Mode session
– ✅ Version and CODEOWNERS-protect notepad files
– ✅ CI that fails on notepad ↔ import graph drift
– ✅ Cite notepad IDs inside agent plans ❌ Don’ts
– ❌ Don’t rely on chat memory for architecture intent
– ❌ Don’t let agents invent event names outside the freeze list
– ❌ Don’t expand dependency edges without an ADR
– ❌ Don’t paste the entire monorepo README into one mega-notepad
– ❌ Don’t skip structured output gates when plans claim compliance

Related reading

Last updated on September 11, 2026

Related: Building AI Agents That Actually Work: The Architecture No Tutorial Shows You · RAG Over ADRs: Architecture Decision Retrieval for Coding Agents · Cursor Background Agents: CI Gates That Catch Hallucinated AWS Changes

Related: Big O Notation Explained: The Complete Guide Every Developer Must Know · Database Indexing: The Complete Guide to Indexes Every Developer Must Understand · Day 82: Voice and Realtime Agents

Watch: 100 Days of AI on YouTube

Short videos from CheatCoders, one AI engineering topic per day.

Open the playlist on YouTube · CheatCoders on YouTube

Deep-dive PDF

Get the expanded guide for this post — extra diagrams-style checklists, failure modes, and a production walkthrough. Free when you subscribe to CheatCoders.

Already subscribed? or open the subscribe page.


Discover more from CheatCoders

Subscribe to get the latest posts sent to your email.

Comments

No comments yet. Why don’t you start the discussion?

Leave a comment

No account needed. Name and email are optional.