AI EngineeringZero to ProductionHome·About·What’s new·Contact
AI-Assisted Development · Chapter V2

AI-Powered Development with Cursor AI

Cursor is an AI-first code editor — a VS Code fork rebuilt around the model living inside the editor rather than bolted on. This chapter tours its core surfaces (Tab, inline edit, chat, agent), the context system that makes it accurate, and how to keep control as its autonomy climbs.

⏱️ ~1.5 hours🧪 1 labs🎯 Beginner→Tech-lead

Learning objectives

  • Set up Cursor and use its core surfaces (Tab, Cmd-K, chat, agent).
  • Feed the model the right context for good edits.
  • Use rules and the agent for multi-file changes safely.
  • Adopt Cursor across a team with governance.
▶ Runnable companionEvery code block in this lesson is also a standalone file under code/ad2-cursor/ in the course, with a README on how to run it. Read here, run there — no need to copy-paste.

1 · What Cursor is essential

You've probably already tried "AI in your editor" and been underwhelmed. A little autocomplete plugin suggests the end of a line, you tab it, and that's the whole relationship — the model is a guest sitting in a side panel, occasionally handed a scrap of your file and asked to guess. Cursor starts from the opposite premise: what if the model didn't visit the editor but lived in it — able to read your whole repository, edit files directly, and carry out a multi-step task on its own? That single design flip is the reason this chapter exists, and it changes how you work more than any one feature does.

Here's a useful way to hold it in your head: think of the difference between a dictionary sitting on your desk and a fluent colleague sitting next to you. The dictionary (old-style autocomplete) answers exactly what you point at, one word at a time, with no idea what you're building. The colleague (Cursor) has read the codebase, understands what you're trying to do, and can go make a change across several files while you watch. Same underlying language model — completely different amount of context and agency wired into it. Everything else in this lesson is really about managing that context and that agency.

Concretely, Cursor is a VS Code fork rebuilt around the model. Because it's a fork, everything you already know about VS Code — extensions, keybindings, the terminal, your settings — still works, so there's no editor to relearn; the AI is simply woven through it. The common beginner mistake is to keep treating it like plain VS Code with a fancier autocomplete and never touch the deeper surfaces. The AI isn't a side panel — it edits your files, reads your repo, and runs multi-step changes. It exposes four surfaces, and the skill this whole chapter builds is knowing which one to reach for: Tab (autocomplete), Cmd-K (inline edit), chat (ask about the codebase), and the agent (multi-file tasks). Each is a different point on a dial from "tiny, instantly-verifiable suggestion" to "large, autonomous change you must review" — and matching the surface to the job is what separates someone who's fast and safe with Cursor from someone who's just fast.

old-style autocomplete editor your files model bolted on one scrap handed over · guesses the rest Cursor — a VS Code fork editor model lives inside reads repo · edits · runs whole codebase in reach · has agency The model doesn't visit the editor — it lives in it. Old autocomplete is a plugin beside your files, handed one scrap and left to guess; Cursor is a VS Code fork built around a model that reads the whole repo, edits files, and runs multi-step tasks.
🗺️ How to read this diagram

Compare the two panels left to right — the left is the world you already know, the right is Cursor's flip.

  • On the left, the model is a small box outside the editor, connected by a thin dashed arrow: it's "bolted on" and only ever sees the one scrap of your file you point at, so it guesses everything else.
  • On the right, the model box sits inside the green editor box — it lives in the tool, can read the whole repo, edit files directly, and run multi-step tasks.
  • The payoff is that same-inside-vs-outside placement: the difference isn't a better model, it's how much context and agency the model is wired into. Everything else in the chapter is about managing that.

In short: a guest in a side panel guesses; a model living in the editor reads your whole codebase and acts on it.

2 · The four surfaces essential

The fastest way to get frustrated with Cursor is to use the wrong surface for the job. People open the agent to finish a single line, or type a whole feature request into Tab and wonder why nothing happens. The four surfaces aren't four flavours of the same thing — they're four different sizes of request, and each one asks a different amount of trust from you. Picking the right size up front is most of the skill.

The organizing idea is a dial that runs from tiny and instant to big and autonomous. Think of the range of ways you'd ask a capable colleague for help. Sometimes you just want them to finish your sentence (Tab) — you'll see instantly whether it's right, so there's almost no risk. Sometimes you want them to reword the paragraph you've highlighted (Cmd-K) — a bounded edit to a piece you've already selected. Sometimes you don't want an edit at all, you want to ask a question and understand something (chat). And sometimes you hand them a whole task — "add pagination end to end" — and let them go work across several files, run commands, and come back with a proposal (agent). The bigger the ask, the more autonomy you grant, and the more carefully you have to check what comes back.

The rule that falls out of this — and it's worth tattooing on your workflow — is use the lightest surface that does the job. Verification is the hidden cost of every AI edit: a Tab completion you can eyeball in a second, but an agent run can touch a dozen files and needs a real diff review. If a change is small and mechanical, don't summon the agent just because it's powerful; you'll pay in review time for autonomy you didn't need. Read the table below not as four features to memorize but as that dial, left (cheapest to verify) to right (most powerful, most to review) — and let "how bounded is this change, and how fast can I check it?" pick the surface for you.

one dial: smaller ask on the left, bigger ask on the right Tab finish a line Cmd-K edit a selection Chat ask / plan Agent multi-file task tiny & instant big & autonomous autonomy granted → and verification cost → both rise together rule: use the lightest surface that does the job Four surfaces, one dial. Tab → Cmd-K → Chat → Agent is a spectrum from a tiny, instantly-checkable suggestion to a large, autonomous change — and the further right you go, the more you must review what comes back.
🗺️ How to read this diagram

Read the four boxes left to right — that's the dial, from the smallest kind of request to the largest.

  • Each box is one surface: Tab finishes a line, Cmd-K edits a selection you highlighted, Chat answers a question or plans, and the Agent takes a whole task across many files. The colour warms left-to-right (blue → white → green → amber) as the request gets bigger.
  • The arrow underneath is the dial itself: it runs from "tiny & instant" on the left to "big & autonomous" on the right. Moving right grants the model more autonomy.
  • The payoff is the line below the arrow: autonomy and verification cost rise together. A Tab completion you eyeball in a second; an Agent run needs a real diff review — so the right choice is the leftmost surface that still does the job.

In short: match the surface to how bounded the change is — the bigger the ask, the more you pay to check it.

SurfaceTriggerUse for
Tabtypingnext-edit prediction, boilerplate
Cmd-Kselect + Cmd-Kedit this selection/function
ChatCmd-Lunderstand code, plan a change
Agentchat + agent modemulti-file feature, run + fix

3 · Intermediate — context is everything intermediate

Here's the single idea that, once it clicks, makes you dramatically better at Cursor overnight. The model does not know your codebase. It cannot see your files unless something puts them in front of it. When you type "fix this bug" with nothing attached, the model isn't being lazy or stupid — it's answering the only way it can, by guessing what your code probably looks like based on the millions of other codebases it saw in training. Sometimes the guess is close. Often it invents a function that doesn't exist, imports a library you don't use, or "fixes" a bug in a version of your file that lives only in its imagination.

The analogy that makes this concrete: imagine texting a brilliant senior engineer who is not looking at your screen. If you text "the login is broken, fix it," the best they can do is describe a generic login fix — they're guessing at your stack. If instead you text "login throws a 500 — here's the authenticate() function [paste], here's the User model [paste], and here's the stack trace [paste]," they can point at the exact broken line. Same engineer, same question — the difference in the answer is entirely the context you handed over. Cursor's @-references are how you paste those things without leaving the editor.

Cursor is only as good as the context you give it. Use @file, @folder, @docs, and @web to point it at exactly what matters. Vague prompt + no context = generic code; precise prompt + the right files = a correct edit. The common beginner trap is spending all your effort polishing the wording of the prompt while attaching nothing — a beautifully phrased request over an empty context still leaves the model guessing. The reverse is far more effective: attach the two or three files that actually matter and even a terse ask lands well. That's exactly why the little scorer in the lab below rewards attached context more than clever phrasing — because in practice, pointing the model at the right files is the highest-leverage move you can make, and it's the one beginners skip.

same model — the difference is the context you hand it "fix this bug" no files attached "fix this bug" @auth.py @User + stack trace pasted model same LLM guessed code invented funcs / wrong file targeted fix points at the broken line context in → correctness out The context, not the wording, decides the answer. The identical ask "fix this bug" produces guessed code with nothing attached, and a targeted fix once you point the model at the real files and the error — which is why the scorer rewards attached context most.
🗺️ How to read this diagram

Both rows send the same request to the same model in the middle — read each row left (the prompt) to right (what you get back).

  • The top red row is "fix this bug" with nothing attached. The dashed grey arrows mean the model is working blind; it flows out to guessed code — invented functions or edits to a file it imagined.
  • The bottom blue row is the identical ask, but with @auth.py, the @User symbol, and the pasted stack trace attached. The solid blue arrows mean the model can see the real code; it flows out to a green targeted fix on the actual broken line.
  • The payoff is that both paths pass through the same LLM — so the only thing that changed the result is what you handed over. That's the line at the bottom: context in → correctness out.

In short: attach the two or three files that matter and even a terse prompt lands; polish the wording over an empty context and it still guesses.

Example code for learning — review, test, and adapt it before running against real or production systems. Commands can create, change, or delete resources. See the Terms & Disclaimer.
Python · score how well-specified a Cursor request is (runs)
prompt_quality.pydef prompt_quality(text, at_refs, has_acceptance):
    score = 0
    score += 2 if len(text.split()) >= 8 else 0     # specific ask
    score += min(len(at_refs), 3)                   # @file/@folder context
    score += 1 if has_acceptance else 0             # "it should ..." criteria
    verdict = "good" if score >= 4 else "too vague — add context/criteria"
    return score, verdict

print(prompt_quality("add pagination to the users endpoint",
                     at_refs=["@users.py", "@schema.sql"], has_acceptance=True))
print(prompt_quality("fix it", at_refs=[], has_acceptance=False))
(6, 'good')
(0, 'too vague — add context/criteria')
▶ How this works

This little program scores how well you asked Cursor for something. The idea: the AI can only give a good edit if your request is specific and points at the right files. So this function turns that intuition into a number you can check before you hit send.

  1. def prompt_quality(text, at_refs, has_acceptance): takes three inputs — the words of your request (text), a list of @file/@folder references you attached (at_refs), and whether you stated success criteria (has_acceptance).
  2. score += 2 if len(text.split()) >= 8 else 0 — text.split() breaks the sentence into words and len(...) counts them. A request with 8+ words earns 2 points for being specific; a two-word ask like "fix it" earns 0.
  3. score += min(len(at_refs), 3) adds one point per attached file, but caps at 3 — pointing the AI at the exact files is the biggest win, so it's rewarded most.
  4. score += 1 if has_acceptance else 0 gives a point for telling the AI what "done" looks like (an acceptance criterion, e.g. "it should return 404 on unknown id").
  5. verdict = "good" if score >= 4 else "too vague ..." — 4 or more means the request is worth sending; below that, add context or criteria first. The function hands back both the score and the verdict.

What the output means: The first call (a clear ask + two @ files + criteria) scores (6, 'good'). The second call, just "fix it" with nothing attached, scores (0, 'too vague — add context/criteria') — exactly the kind of prompt that makes the AI guess.

Try this: Take a real request you'd type into Cursor and run it through this function. If it scores below 4, add an @file and a one-line "it should…" until it reaches good — that habit alone dramatically improves the edits you get back.

4 · Advanced — rules & the agent advanced

Notice a chore creeping into your Cursor sessions: every few prompts you find yourself re-typing the same reminders. "Use type hints." "We use pytest, not unittest." "Don't touch the generated folder." You're acting as the model's memory, and it's tedious and error-prone — forget the reminder once and the AI happily writes code in a style your reviewer will reject. Project rules exist to end that chore, and the agent exists to take on the tasks too big for a single edit. This section is where Cursor stops being a smarter autocomplete and starts being something that works on your behalf.

Take rules first. A .cursor/rules file is a set of standing instructions Cursor silently prepends to every request in the project — think of it as an onboarding doc the AI actually reads before every single task, instead of a wiki page a new hire skims once and forgets. Your conventions, your stack, your do/don'ts, written once and committed to the repo so every teammate's Cursor obeys the same rules. That's the leverage: you encode "how we do things here" a single time, and it shapes thousands of future edits. The important honesty here — and the next section's exercises hammer it — is that rules are strong hints, not hard walls; they steer the common case beautifully but a determined model wrestling a big diff can still drift, which is why real "must-nevers" belong in a linter or CI, not just a rule.

Then the agent. Where Tab and Cmd-K make one edit you asked for, the agent takes a goal and figures out the steps: it plans, edits across files, runs commands, reads the errors, and fixes its own mistakes — a loop that keeps going until the task looks done or it gets stuck. That autonomy is genuinely powerful and genuinely the risk of the chapter: the same speed that lets it wire up a feature across six files also lets it introduce a subtle bug in a seventh you weren't watching. So the discipline arrives with the power — review its diff before accepting, every time, which is exactly the professional habit the next section is built around. For now, read the rules file below as the AI's permanent instructions, and remember it produces no output on its own; it just quietly bends every later request toward your conventions.

the agent takes a goal and loops until done — then hands you a diff to review goal what you ask plan break into steps edit files across the repo run + read cmds & errors your diffreview accept / reject fix & repeat looks done → speed is the power AND the risk — the loop ends at YOUR review, not at "tests pass" The agent is a loop, not a single edit. From your goal it plans, edits across files, runs commands and reads the errors, then loops back to fix itself — and when it looks done the loop lands on your diff review, which is why that review is non-negotiable.
🗺️ How to read this diagram

Start at the blue goal box on the left and follow the solid arrows clockwise through the cycle.

  • From your goal, the agent plans (breaks the task into steps), then edits files across the repo, then runs commands and reads the errors — the amber box is where it checks its own work.
  • The dashed "fix & repeat" arrow curls back up to plan: when something failed, the agent fixes it and goes round again. That self-correcting loop is what makes it feel autonomous.
  • The payoff element is the green box on the right: when the work looks done, the loop does not stop at "tests pass" — it stops at your diff review, where you accept or reject. The bottom line names the trade: the same speed that powers the loop is also the risk, so the human review is the last, mandatory step.

In short: the agent loops plan → edit → run → fix on its own, but the loop only closes when you review the diff.

.cursor/rules/conventions.mdc · project rules
conventions.mdc---
description: Team conventions Cursor must follow
alwaysApply: true
---
- Python: type hints on all public functions; use pytest, not unittest.
- Never edit files under `generated/` or `migrations/`.
- Prefer stdlib; ask before adding a dependency.
- All new endpoints need a test in tests/ and an entry in the OpenAPI spec.
▶ How this works

This is a Cursor rules file — a small config you commit into your project at .cursor/rules/. Whatever you put here gets quietly added to every request you make to Cursor, so the AI follows your team's conventions without you re-typing them each time.

  1. The block between the two --- lines is called front matter — settings, not instructions. description: is a human label, and alwaysApply: true means "attach this to every request in the project" (rather than only when relevant).
  2. Everything below the front matter is the actual guidance, written as plain-English bullet points. Python: type hints on all public functions; use pytest, not unittest. tells the AI which style and test framework you expect — so its generated code matches your codebase.
  3. Never edit files under `generated/` or `migrations/`. is a guardrail: these folders are produced by tools, so hand-edits (even the AI's) would be overwritten or break things.
  4. Prefer stdlib; ask before adding a dependency. keeps the AI from silently pulling in new packages — a common way AI edits bloat a project.
  5. The last rule ties new endpoints to a test and an OpenAPI entry, so the AI's work stays complete and reviewable, not just "code that runs".

What the output means: This file produces no output on its own — it's not run like a program. Instead Cursor reads it and silently prepends these rules to your prompts, so the AI's answers already respect them.

Try this: Create .cursor/rules/conventions.mdc in a small project, add one rule you care about (e.g. "always add a docstring"), then ask Cursor to write a function and watch it follow the rule without being reminded. Committing this file means every teammate's Cursor behaves the same way.

5 · Professional — review the diff, always professional

This is the habit that separates professionals from people who eventually get burned. The agent runs, the terminal scrolls, the tests go green, and there's a powerful pull to just click Accept and move on — the code works, doesn't it? That instinct is exactly the trap. "Tests pass" only proves the code doesn't break the things you happened to test; it says nothing about the untested branch it quietly rewrote, the extra file it edited "while it was in there," or the secret it helpfully hard-coded. Green is a floor, not a ceiling.

The mental reframe that fixes this: an agent's edit is a proposal, not a fact. Treat every agent run exactly like a pull request from a talented but junior developer — one who is fast, eager, and occasionally does something surprising because they didn't share your context. You would never merge a junior's PR unread just because CI was green; you read every line, you question the changes you didn't ask for, and you check the negative space — did they add tests for the new paths, did they remove something they shouldn't have? The same standard applies here, and it does not relax because a machine typed the code.

Here's the part people miss: your job as the human doesn't shrink when the AI writes the code — it shifts. You spend less time typing and more time judging, and judging well is the harder, more valuable skill. The velocity is real and worth having, but velocity without review is precisely the mechanism by which AI edits slip subtle, expensive bugs into a codebase that nobody notices until production. Keep diffs small and single-purpose so they're actually reviewable; reject a sprawling multi-concern change and ask the agent to split it. In short:

the whole agent change tests pass what you tested untested branch edits made in passing scope creep hard-coded secret ← the negative space your diffreview read every line green is a floor, not a ceiling — an edit is a proposal, not a fact "Tests pass" only covers what you tested. The green box is a small slice of the change; the surrounding negative space — untested branches, in-passing edits, scope creep, a hard-coded secret — is exactly what a human diff review has to catch.
🗺️ How to read this diagram

Read the big outer box as the entire change the agent made, then compare the small green slice against everything around it.

  • The green box is what "tests pass" actually proves — only the paths you happened to test. It is deliberately small inside the whole change.
  • The red labels filling the rest are the negative space green tells you nothing about: an untested branch it rewrote, files it edited "while it was in there," scope creep, a helpfully hard-coded secret.
  • The payoff is the arrow to the amber your diff review box: the only thing that inspects the whole rectangle — not just the green slice — is you reading every line. Green is a floor, not a ceiling.

In short: passing tests cover a corner of the change; the human review is what covers the rest, so an agent edit is a proposal you read line by line, not a fact.

The agent can touch many files fast — that's the power and the risk. Treat every agent run like a PR from a junior dev: read the diff, run the tests, don't accept blindly. Speed without review is how AI edits introduce subtle bugs.

6 · Tech-lead — rolling Cursor out to a team tech-lead

The classic way to roll out a tool like this fails quietly. A lead buys thirty licenses, sends a "Cursor is live!" email, and declares victory. Six weeks later the codebase has thirty subtly different styles, review queues are clogged with giant unreviewed AI dumps, and the incident rate is creeping up while everyone insists they're "shipping faster." Nothing dramatic broke — the rollout just optimized for the wrong thing. Handing out access is the easy 5%; the process around it is the 95% that decides whether this becomes a real team gain or a slow-motion quality regression.

The reframe for a lead: you're not rolling out a tool, you're rolling out a practice. Everything you learned as an individual in the sections above — attach the right context, encode conventions in rules, review every diff — has to become the team's default, not each person's private discovery. And because the tool's value is famously bimodal on skill (the same license makes a careful engineer much faster and a careless one much more dangerous), the lever is training the habits, not distributing the licenses. Two things especially don't scale by osmosis and must be made explicit: the verify discipline and context-attachment muscle memory.

The other half of the job is guardrails and measurement, because trust alone doesn't hold at thirty people. Some conventions are non-negotiable and belong in tooling the model can't overrule — secret-scanning in CI, indexing settings that respect what may leave your network, repos that are simply off-limits. And you have to watch the right dials: it's tempting to celebrate a falling PR cycle time, but if review time is rising and incidents are ticking up, you've bought speed by spending quality — the exact trade a good rollout is designed to catch early. A sensible sequence is a small pilot first, then shared rules, then the review standard, then org-wide. In practice:

roll out a practice, not just a license — stage it, and watch two dials pilot 3–5 for 2 weeks shared rules one .cursor/rules review standard diffs like PRs org-wide 30 engineers measure BOTH dials, not just speed speed ↑ PR cycle time down quality ↓ ? review time up · incidents up a good rollout catches the speed-for-quality trade early Roll out the practice in stages, and watch two dials. Pilot → shared rules → review standard → org-wide; then measure quality (review time, incidents) alongside speed, or you'll buy velocity by silently spending quality.
🗺️ How to read this diagram

Read the top row left to right as the rollout sequence, then look at the two boxes below as the dials you watch the whole time.

  • The top four boxes are the stages in order: a small pilot, then a committed shared rules file, then a review standard (agent diffs reviewed like PRs), then org-wide. You don't jump straight to thirty licenses.
  • The green box below is the dial everyone celebrates — speed up, PR cycle time down. The red box beside it is the dial people forget: review time rising and incidents ticking up.
  • The payoff is watching both: a falling cycle time is only a win if quality holds. If the red dial is climbing you've bought speed by spending quality — the exact trade a staged, measured rollout is designed to catch early.

In short: stage the rollout and measure quality next to speed — the failure mode is treating it as a license drop and watching the speed dial alone.

A lead standardizes the setup: shared .cursor/rules in the repo, a model policy (which models, privacy mode for sensitive code), a norm that agent diffs go through review, and guidance on when to use Tab vs agent. This turns individual speedups into a consistent team gain without a quality regression.

Rules in the repo = consistent AI across the teamCommitting .cursor/rules means every engineer's Cursor follows the same conventions — the AI becomes part of your codebase's standards, not a per-person wildcard. This is the single highest-leverage team setup step.

Exercise AD2.1 — A well-specified agent task

Context: A well-specified agent task combines the levers you just learned: a rules file, precise @ context, and explicit acceptance criteria — then reviewing the diff before accepting. This is the full Cursor loop in one exercise.

Your task: Write a .cursor/rules file for a small project, craft an agent request with proper @ context and acceptance criteria, score it, run it, and review the diff.

Requirements:

  • Write a .cursor/rules file encoding the project's conventions
  • Craft the agent request with proper @file/@folder/@symbol context and explicit acceptance criteria
  • Score the prompt with prompt_quality.py and aim for ≥4
  • Run it, then review the full diff before accepting

💡 Hint: The score rewards attached context most heavily — point the model at the exact relevant files before you tune the wording.

🪜 Practice ladder beginner → industry

Six graded exercises, easy to real-world. Try each before opening its solution.

Exercise 1 · Match the surface to the taskBeginner

Context: Cursor exposes four surfaces and the core skill is matching the surface to the task so verification stays cheap. Use the lightest surface that fits.

Your task: For each task pick the right Cursor surface: rename a variable everywhere, ask ‘how does auth work here’, finish a line, implement a feature across files.

Requirements:

  • Finish a line → tab/autocomplete (lowest friction, instant verify)
  • Rename everywhere → inline edit (or agent for cross-file) — a scoped mechanical change
  • ‘How does auth work?’ → chat (a question, no edit)
  • Feature across files → agent (multi-file, needs planning and tool use)
  • State the principle: use the lightest surface that fits so verification stays cheap

💡 Hint: Match surface to task by how bounded the change is and how fast you can check it.

Show solution
TaskSurface
Finish a lineTab / autocomplete — lowest friction, instant verify
Rename a variable everywhereInline edit (or agent for cross-file) — a scoped mechanical change
‘How does auth work here?’Chat — a question, no edit needed
Implement a feature across filesAgent — multi-file, needs planning & tool use

Matching surface to task is the core Cursor skill: use the lightest surface that fits so verification stays cheap.

Exercise 2 · Context is everythingIntermediate

Context: The model only knows what's in its context window, so the same prompt with the right files attached goes from guessing to grounded. Adding context is the highest-leverage move in Cursor.

Your task: Explain why the same prompt gives better results with the right context, list the concrete ways to add context in Cursor, and give a worked example.

Requirements:

  • Explain that the model is limited to its context window — right files turn guessing into grounding
  • List the context mechanisms (@file/@folder, @symbol, the open file, pasted errors, codebase indexing)
  • Give a worked before/after (‘fix this bug’ vs the same with the failing function, its type, and the stack trace attached)
  • Conclude that adding context is the highest-leverage move in Cursor

💡 Hint: Attach the exact function, the type it operates on, and the error — precise context in, targeted fix out.

Show solution

The model only knows what is in its context window. The same prompt with the right files attached goes from guessing to grounded.

Ways to add context in Cursor: @file/@folder to attach code, @symbol for a specific function/type, referencing the open file, pasting an error, and codebase indexing for whole-repo search.

Worked example: ‘fix this bug’ alone → the model guesses. ‘fix this bug — @auth.py @User here's the stack trace [paste]’ → it sees the failing function, the type it operates on, and the exact error line, so the fix is targeted. Adding context is the highest-leverage move in Cursor.

Exercise 3 · Rules that actually steer the agentAdvanced

Context: Project rules apply to every request, so good ones encode your conventions and make the agent's output look like your codebase instead of a generic one.

Your task: Write three project rules that would meaningfully change generated code quality and say what each prevents.

Requirements:

  • Write three concrete rules that steer the agent (e.g. use the existing DB session, validate with existing schemas, write tests alongside code)
  • For each rule, name what it prevents
  • Make the rules encode your conventions, not generic best practices
  • Explain that good rules make the agent's output match your codebase

💡 Hint: The best rules point at existing patterns to reuse — they stop the agent inventing a second, inconsistent way to do a thing you already do.

Show solution
1. Use the existing `db.session` for DB access; never open raw connections.
2. All new endpoints must validate input with the Pydantic models in schemas/.
3. Write pytest tests alongside new functions; match the style in tests/.
RulePrevents
Use existing db.sessionThe agent inventing a second, inconsistent DB access pattern
Validate with existing schemasUnvalidated endpoints & duplicated ad-hoc validation
Tests alongside codeUntested generated logic slipping in

Good rules encode your conventions, not generic best practices — they make the agent's output look like your codebase instead of a generic one.

Exercise 4 · Why the agent went wrongExpert

Context: Rules are strong hints in context, not hard constraints — they compete for attention with a big diff and can lose, especially to a deprecated API that's common in training data or still present in the repo. Making them stick needs enforcement outside the model.

Your task: Diagnose why an agent used a rule-forbidden deprecated API even though it had the rule, and how to make rules stick.

Requirements:

  • Explain that rules are soft hints that compete for attention and can lose
  • Remove the temptation: delete the deprecated API from the repo or fail CI on its use
  • Make the rule specific and local (‘never X; use Y — example: [snippet]’) not vague
  • Enforce non-negotiables outside the model with a linter/CI gate the model can't overrule
  • State the lesson: shape the common case with rules, enforce ‘must never’ with tooling

💡 Hint: For a hard ‘must never’ requirement, back the rule with a mechanical gate; a prompt instruction alone is overrulable.

Show solution

Rules are strong hints in context, not hard constraints — they compete for attention with a large diff and can lose, especially when the deprecated API is more common in the training data or still present in the codebase.

  1. Remove the temptation: if the deprecated API still exists in the repo, the agent will pattern-match to it. Delete it or add a lint rule that fails CI on its use.
  2. Make the rule specific & local: ‘never use X; use Y instead — example: [snippet]’ beats a vague ‘follow best practices’.
  3. Enforce outside the model: a linter/CI check is a hard constraint; a rule is a soft one. For ‘must never’ requirements, back the rule with a mechanical gate.

Lesson: use rules to shape the common case, but enforce non-negotiables with tooling the model can't overrule.

Exercise 5 · Always review the diffProfessional

Context: ‘Tests pass’ proves the code doesn't break what you tested — it misses everything untested. The reviewer's job doesn't shrink because a machine wrote the code; it shifts from typing to judging.

Your task: Explain what ‘tests pass’ misses on a Cursor agent change and the review discipline you'd require before merge.

Requirements:

  • Name what green tests miss (unnecessary in-passing changes, wrong logic in untested branches, security/secrets, scope creep, unmaintainable-but-working code)
  • Require reading every line of the diff — edits are a proposal, not a fact
  • Require questioning surprise changes and understanding or reverting unexpected file edits
  • Require checking the negative space (tests for new branches, nothing wrongly removed) and keeping changes scoped
  • State that the reviewer's job shifts from typing to judging

💡 Hint: Treat every agent run like a PR from a junior developer: read the whole diff and question anything you didn't ask for.

Show solution

Green tests prove the code does not break what you tested. They miss: unnecessary changes the agent made in passing, subtly wrong logic in untested branches, security/secret issues, scope creep, and ‘works but is unmaintainable’ code.

  1. Read every line of the diff — the agent's edits are a proposal, not a fact.
  2. Question surprise changes: if it touched a file you didn't expect, understand why or revert it.
  3. Check the negative space: did it add tests for the new branches? Did it remove anything it shouldn't?
  4. Keep changes scoped: reject giant multi-concern diffs; ask the agent to split them.

The reviewer's job doesn't shrink because a machine wrote the code — it shifts from typing to judging.

Exercise 6 · Rolling Cursor out to a 30-person teamIndustry scenario

Context: Rolling an AI tool out to 30 engineers succeeds on process — shared rules and review discipline — not on the license. Measuring quality, not just speed, is what catches a speed-for-quality trade before it becomes incidents.

Your task: As the tech lead adopting Cursor across a 30-engineer org, design the rollout: standards, guardrails, and how you'll know it worked.

Requirements:

  • Start with a small pilot before org-wide rollout
  • Ship shared project rules so everyone's agent produces consistent code, not 30 personal styles
  • Set the review standard (AI-authored code reviewed like any code; author accountable; scoped, tested diffs)
  • Add guardrails: secret-scanning in CI, indexing/data settings that respect the network boundary, off-limits repos
  • Invest in training the verify + context-attachment habits, not just handing out licenses
  • Measure quality (bug/incident rate, review time) alongside speed to catch a bad trade

💡 Hint: The failure mode is treating it as a license rollout and measuring only speed — watch quality signals too.

Show solution
  1. Start with a pilot: 3-5 volunteers for 2 weeks; collect what worked and what bit them before org-wide.
  2. Ship shared rules: commit a project .cursor/rules encoding team conventions so everyone's agent produces consistent code — not 30 personal styles.
  3. Set the review standard: AI-authored code is reviewed like any other; author is accountable; diffs stay scoped and tested (reuse the PR standard).
  4. Guardrails: secret-scanning in CI, codebase indexing settings that respect what may leave the network, and a policy on which repos are off-limits.
  5. Training, not just licenses: teach context-attachment and the verify habit — the tool's value is bimodal on skill.
Success signalWatch for
PR cycle time downReview time up (unreviewed dumps)
Bug rate flat or downRising incident rate from unowned code
Devs report less toilOver-reliance on unverified generations

Lesson: the rollout succeeds on process (shared rules + review discipline), not on the license. Measure quality, not just speed.

✓ Checkpoint — you can move on when you can…

  • Use Tab/Cmd-K/chat/agent for the right jobs.
  • Feed context with @file/@folder/@docs.
  • Write project rules and drive the agent.
  • Review every diff; roll out with shared rules + a model policy.

Knowledge check check yourself

✓ Knowledge check

Cursor's prompt_quality scorer weights attached @file/@folder references most heavily (up to 3 points). What does that design choice say about what most improves a Cursor edit?

Show answer
Pointing the model at the exact relevant files is the single biggest lever on edit quality — precise context in yields a correct edit out, whereas a specific ask with no context still leaves the model guessing at your codebase.
✓ Knowledge check

Why does the lesson insist you treat every Cursor agent run like a PR from a junior developer, reviewing the diff before accepting?

Show answer
The agent can touch many files fast, so its speed is both the power and the risk; without reading the diff and running tests, that velocity silently introduces subtle bugs across the codebase.
© 2026 studybydoing.in · AI Engineering: Zero to Production · All rights reserved. · About · Privacy Policy · Terms · Contact
Educational content, provided as-is and without warranty. Code samples are examples — review, test, and adapt them before using in production. See the Terms of Use & Disclaimer. Use at your own risk.
© studybydoing.in