Agentic Workshop
Module 04 · 55 min

Context engineering, memory and planning

More context does not automatically mean more quality. This module teaches you to select what changes a decision, keep project instructions concise, and test what survives between sessions.

Lessons

What you will tackle, step by step

4.1

Four practical sources of context

When you work with an agent, context is not a single pile of information. It is the set of what the agent can use to decide the next step. Separating the types helps you understand what to provide, what to test and what to leave out.

Here we use four practical sources, not a complete list of everything that can fit into the context: the current request, observed files and outputs, persistent instructions, and memory. `CLAUDE.md` contains rules written by you; auto memory contains notes that Claude keeps between sessions. Confusing them produces temporary rules that become permanent or old memories treated as current facts.

Each element should answer a question: is it needed to decide now? Will this remain true next week? Can it be verified in the repository? Does it contain data that should not be shared?

See it in practice · Add currency to invoices without inventing context

You must show EUR or USD next to the total. The repository contains an Invoice model, a formatting function and an old note that only talks about euros.

  1. Write the current request in a verifiable sentence: “show the currency saved in the invoice, without changing the existing amounts”.
  2. Open model, migrations, formatter and test: find that the currency field already exists and that USD is already allowed by the database.
  3. Read stable instructions: For money the project requires Intl.NumberFormat and prohibits implicit conversions. Treat the old note on the euro as a memory to be verified, not as truth.
  4. Build the final context with those files, the format constraint, and two test invoices; exclude customer dumps and payment service keys.

Result: The agent can make a small and consistent change: it uses the field already available, respects the project convention and does not assume that all invoices are in euros.

4.2

Project instructions that really help

The project instructions are a small operating manual for those who work on the code. They don't have to tell the whole story of the product: they have to avoid errors that a simple reading of the files doesn't make evident.

A good instruction file indicates reliable commands, architectural boundaries, non-obvious conventions, and Definition of Done. Avoid project bios, duplicate opinions, and already easy-to-read information from files.

Write positive and testable rules: “run pytest -q” is more operational than “pay attention to tests”. Remember, however, that `CLAUDE.md` guides the model, it is not a firewall: a rule that must always be triggered must be made technical with permissions, hooks or tests. Add exceptions only when there is a real reason and remove a rule when it is no longer true.

See it in practice · A clear rule for translation files

On the site, some people directly edit `messages.generated.json`; on the next build the generator overwrites everything and the translation disappears.

  1. Confirm from the build files that `messages.generated.json` is indeed generated and locate `locales/source.it.json` as the editable source.
  2. Add a positive instruction: edit the source file only, then execute `npm run i18n:build`; don't just write "don't touch the wrong files".
  3. Define the evidence: `git diff` must show both the source and the generated file, and `npm run i18n:check` must terminate with no missing keys.
  4. Test the instruction with a new label and have a person who doesn't know the generator read the text; if it has to ask which file to open, the rule is still incomplete.

Result: The next change follows a repeatable path and leaves evidence you can inspect. The instruction file contains a non-obvious convention, not a copy of the general documentation.

4.3

Compact without losing the contract

Compacting means turning a long conversation into a short handoff. The goal is not to remember every sentence: it is to maintain the operating contract necessary to resume without reinterpreting the work.

As a conversation grows, a summary reduces the volume but can eliminate details. Before compaction, identify decisions, constraints, files modified, evidence obtained, and remaining work. Then, check that these elements are still explicit.

A new session should be able to resume from the repository and a short handoff, not by blind trust in memory. After `/compact`, Claude Code rereads the `CLAUDE.md` at the repository root; nested instructions and path-specific rules return when you reopen the relevant files. The state of the files remains the primary source for what has actually changed.

See it in practice · Resume a cart correction the next day

You have isolated a double charge when the user presses “Pay” twice. The session is long and you must stop before complete verification.

  1. Record the contract: only one payment request per order, no changes to the refund flow and no log with card details.
  2. Note the decision: use an order-derived idempotence key; reports that the attempt to disable only the button was discarded because it does not cover duplicate requests from the network.
  3. List the files actually changed and the available evidence: new test failed before patch and is green after; end-to-end testing has not yet been performed.
  4. Compare handoff, `git status` and diff on resume, then run the missing check in a test environment before declaring the job done.

Result: The new session starts from the risk still open, does not reconstruct the entire discussion and does not confuse a successful unit test with a complete payment verification.

4.4

Plan before execution

Not every job deserves a huge plan. Changing a label can take three lines; changing data read by two versions of the app requires compatible phases and a return path. A useful plan makes this very difference visible before the expensive part begins.

Planning is useful when the change crosses multiple boundaries, real alternatives exist, or the cost of an error is high. The plan must name open files, dependencies, checks, and decisions; it must not simulate certainty on details not yet inspected.

For a local and reversible change, a three-line plan may be sufficient. The depth of reasoning must be proportionate to the risk: spending a lot of time on an obvious change is as inefficient as improvising a complex migration.

  1. Define outcome, boundaries and risk of change.
  2. Locate files, instructions and sources that can change the decision.
  3. Write small steps with open dependencies and decisions.
  4. Associate each step with observable evidence.
  5. Approve execution only when the plan is verifiable.
See it in practice · Migrate customer name without stopping orders

You want to replace `customer_name` with `first_name` and `last_name`, but the old mobile app will remain active during the release.

  1. Map readers and writers of the column and mark the main unknown: for some customers there is only one company name, so automatic splitting is not reliable.
  2. Plan a compatible phase: add the new nullable columns, continue reading the old field, and have the new API write both formats.
  3. Prepare a repeatable backfill on a copy of the data, count ambiguous records and define a safe shutdown if the number exceeds the agreed upon threshold.
  4. Remove old column only after stable metrics, new app adoption and rollback testing; associate verification queries and compatibility tests with each phase.

Result: The change becomes a reversible sequence. Ambiguous cases are not invented and the old app continues to work during the transition.

Guided example

Stable instructions in CLAUDE.md

The project has a test command and an important data boundary.

# Commands
- Tests: pytest -q

# Constraints
- Do not change the task format without an approved migration.

# Definition of done
- Tests and lint are green; summarize the diff and residual risks.