Cursor Notepads: Living Architecture Constraints Agents Must Obey

Cursor Notepads: Living Architecture Constraints Agents Must Obey

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

A notepad is not “extra context.” It is a machine-readable contract the agent must cite before touching files.

# 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
// 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.

# ✅ 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”
# .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.

// 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


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 Reply