Build a Requirements Brief with Claude

Use Claude Code to turn a vague feature request into an evidence-backed brief.

Introduction

30 Second Summary

A short feature request can sound clear until two people imagine different behavior. Those quiet gaps become expensive once code starts treating guesses as facts.

In this project, you will use Claude Code to turn a vague notification request into a verifiable implementation brief. You will preserve the approved decisions as persistent project context that survives across sessions.

What You'll Build

You see a fresh Claude Code session reconstruct an evidence-backed notification brief from repository files alone.

By the end of this project, you'll have:

  • A visible assumption audit that exposes customer-facing choices Claude filled without approval.
  • A durable requirements record that preserves the approved trigger, recipient, channel, failure rules, privacy boundary, and scope across sessions.
  • An evidence-labeled implementation brief that separates approved requirements, observed code behavior, and unresolved decisions without changing source code.
  • An optional Secret Mission to push your skills further.

Are there any prerequisites?

You'll need a Mac running macOS 13 or later, internet access, Git, and Visual Studio Code.

Step 1 handles Claude Code installation and verifies access to an eligible account.

Before We Start

This checkpoint is your commitment to turn BrewQueue's vague notification request into a verifiable brief before Claude Code touches implementation. You will define what you are building and why the agent must pause before writing code.

Set Up a Controlled Claude Code Lab

A requirements experiment only works when you can trace where the agent's answers came from. A controlled repository gives every later claim a visible source.

This step creates that boundary with Claude Code, Git, and Visual Studio Code. Disabling auto memory ensures later sessions rely on files you reviewed.

In this step, get ready to:
  • Prepare an authenticated Claude Code session.
  • Create the BrewQueue fixture inside an initialized Git repository.
  • Confirm that plan mode can inspect the repository without editing it.
Install and authenticate Claude Code

Claude Code runs from a terminal inside your editor. Checking the command first separates an existing installation from a Mac that still needs the native installer.

  • Press Cmd+Space on macOS or the Windows key on Windows to open your search bar.
  • Type Visual Studio Code and press Enter to open it.
  • Click View in the menu bar.
  • Select Terminal to open the integrated terminal.

This check may return a version number or report that the command is unavailable. Both outcomes have a path below.

  • Check whether Claude Code is installed by running:
claude --version

What does this check do?

The command asks the installed Claude Code executable for its version. A version number confirms that your terminal can find the installation.

✔️ I see a version number

Claude Code is installed and available in the Visual Studio Code terminal. Continue with authentication below.

ⓧ Command not found

The native installer downloads Claude Code and makes its command available to your shell.

  • Install Claude Code by running:
curl -fsSL https://claude.ai/install.sh | bash

What does this command do?

This command downloads the recommended native installer from Anthropic. The installer sets up Claude Code for your Mac.

  • Check the completed installation by running:
claude --version

What confirms the installation?

A version number confirms that the installer completed successfully. It also proves that the integrated terminal can locate Claude Code.

Still unable to find Claude Code?

Quit Visual Studio Code completely. Reopen it so the integrated terminal reloads your shell path.

If the command is still unavailable, help me diagnose why the Claude Code installer is missing from my shell path.

Authentication opens a browser so you can approve account access. Your credentials stay out of the BrewQueue files.

  • Start Claude Code by running:
claude

What happens when Claude Code starts?

A first-time session directs you through browser authentication. The terminal returns to the Claude Code welcome session after access is approved.

  • Complete the browser authentication prompts with your eligible Claude Code account.
  • Return to the Visual Studio Code terminal after the browser confirms access.
  • Exit the welcome session by entering:
/exit

Why exit this session?

The welcome session proves authentication works. Exiting keeps it separate from the controlled repository session you create later.

Authentication not completing?

Use the browser link printed in the terminal if a browser window does not open automatically. Confirm that the account you choose includes Claude Code access.

If the terminal remains unauthenticated, help me troubleshoot Claude Code browser authentication on my Mac.

That clears the first hurdle. Claude Code is installed and authenticated before any project history exists.

Create the starter repository

The repository is a deliberately small requirements fixture. Its vague request gives Claude Code enough evidence to inspect while leaving the important notification decisions unresolved.

  • Click File in the Visual Studio Code menu bar.
  • Select Open Folder....
  • Select Desktop in the folder chooser.
  • Click New Folder.
  • Enter brewqueue-requirements-lab as the folder name.
  • Press Enter to create the folder.

The new folder now exists on your Desktop. Visual Studio Code may show a Workspace Trust dialog when you open it because the folder has not been opened before.

  • Select the brewqueue-requirements-lab folder.
  • Click Open.
  • Select Yes, I trust the authors if the Workspace Trust dialog appears.

You should see brewqueue-requirements-lab at the top of the Explorer sidebar.

  • Click View in the menu bar.
  • Select Terminal.
  • Initialize the opened folder as a Git repository by running:
git init

What does this command do?

Git creates repository metadata inside the open brewqueue-requirements-lab folder. That metadata lets later steps track the requirements artifacts as project history.

You should see a message confirming that Git initialized a repository in the current folder.

Git initialization failed?

Confirm that the terminal prompt points to the brewqueue-requirements-lab folder. Reopen the folder in Visual Studio Code if the terminal started elsewhere.

If Git reports another problem, help me diagnose why git init failed in my BrewQueue folder.

The README.md file defines the current behavior and preserves the vague request exactly. It also makes the planning-only boundary explicit.

  • Select brewqueue-requirements-lab in the Explorer sidebar.
  • Click New File... in the Explorer toolbar.
  • Enter README.md as the file name.
  • Add the project description by pasting:
# BrewQueue

BrewQueue is a small order-status domain used for requirements exercises.

## Existing behavior

`src/orderService.js` validates an order status transition and returns the updated order. It does not create or deliver notifications.

## Feature request

Add notifications when an order status changes.

## Project boundary

This repository is a planning fixture. The requirements project stops before implementation.

What does this file establish?

  • The existing behavior gives Claude Code a documented fact about status transitions.
  • The feature request stays vague so the next step can expose unsupported assumptions.
  • The project boundary prevents the requirements exercise from drifting into implementation.
  • Save README.md.
  • Confirm that the editor shows the notification request and the planning-only boundary.

README content looks different?

Check that the file is named README.md in the top level of brewqueue-requirements-lab. Replace any extra text with the reference content above.

If the Markdown structure still differs, help me compare my BrewQueue README with the required fixture.

The source fixture gives Claude Code concrete transition behavior to inspect. The project does not execute this JavaScript file, so no JavaScript runtime is needed.

  • Select brewqueue-requirements-lab in the Explorer sidebar.
  • Click New Folder in the Explorer toolbar.
  • Enter src as the folder name.

You should see the new src folder beneath brewqueue-requirements-lab in Explorer.

  • Select the src folder in Explorer.
  • Click New File....
  • Enter orderService.js as the file name.
  • Add the allowed order transitions by pasting:
export const ALLOWED_TRANSITIONS = Object.freeze({
  RECEIVED: Object.freeze(["BREWING", "CANCELLED"]),
  BREWING: Object.freeze(["READY_FOR_PICKUP", "CANCELLED"]),
  READY_FOR_PICKUP: Object.freeze(["COLLECTED", "CANCELLED"]),
  COLLECTED: Object.freeze([]),
  CANCELLED: Object.freeze([]),
});

What does this code define?

  • The ALLOWED_TRANSITIONS object records every valid next status.
  • Each nested object is frozen so the transition rules remain unchanged during inspection.
  • The empty arrays make COLLECTED and CANCELLED terminal statuses.
  • Save src/orderService.js.
  • Confirm that the editor shows five current statuses under ALLOWED_TRANSITIONS.

Transition table showing errors?

Check every quote and closing bracket against the reference block. Keep the status names in uppercase.

If the editor still highlights the object, help me find the syntax difference in ALLOWED_TRANSITIONS.

  • Place your cursor after the closing line of ALLOWED_TRANSITIONS in src/orderService.js.
  • Add the transition function by pasting:
export function transitionOrder(order, nextStatus, changedAt) {
  const allowedNextStatuses = ALLOWED_TRANSITIONS[order.status] ?? [];

  if (!allowedNextStatuses.includes(nextStatus)) {
    throw new Error(`Invalid transition: ${order.status} -> ${nextStatus}`);
  }

  return Object.freeze({
    ...order,
    status: nextStatus,
    updatedAt: changedAt,
  });
}

What does this function prove?

  • The transitionOrder() function checks the requested status against the allowed next statuses.
  • An invalid transition raises an error before an updated order is returned.
  • A valid transition returns a frozen order with the new status and supplied timestamp.
  • Save src/orderService.js.
  • Confirm that the file now exports both ALLOWED_TRANSITIONS and transitionOrder().

Function highlighted as invalid?

Confirm that the function sits after the transition object. Check the template literal and closing braces against the reference block.

If the syntax remains unclear, help me compare transitionOrder with the BrewQueue reference.

Auto memory can preserve Claude-written notes across sessions. Disabling it at project scope keeps the later clean-session test focused on repository-owned evidence.

  • Select brewqueue-requirements-lab in the Explorer sidebar.
  • Click New Folder.
  • Enter .claude as the folder name.

You should see .claude in the repository tree. This folder holds project-level Claude Code settings.

  • Select the .claude folder.
  • Click New File....
  • Enter settings.json as the file name.
  • Disable project auto memory by pasting:
{
  "autoMemoryEnabled": false
}

Why disable auto memory?

The autoMemoryEnabled setting removes hidden session notes from this experiment. Later sessions must recover decisions from explicit files that you can inspect and review.

  • Save .claude/settings.json.
  • Confirm that Explorer shows README.md, src/orderService.js, and .claude/settings.json.

Settings file not appearing?

Expand the .claude folder in Explorer. Confirm that the file is named settings.json without another extension.

If the setting is rejected, help me compare my project-level Claude Code settings file with the required JSON.

Use the reference tab to compare every starter artifact before you test the controlled session.

✔️ Awesome, I've got everything!

Great. Save all three files before continuing to the session check.

ⓧ I'd like to double check the full code

Compare each file with the complete reference below.

# BrewQueue

BrewQueue is a small order-status domain used for requirements exercises.

## Existing behavior

`src/orderService.js` validates an order status transition and returns the updated order. It does not create or deliver notifications.

## Feature request

Add notifications when an order status changes.

## Project boundary

This repository is a planning fixture. The requirements project stops before implementation.
export const ALLOWED_TRANSITIONS = Object.freeze({
  RECEIVED: Object.freeze(["BREWING", "CANCELLED"]),
  BREWING: Object.freeze(["READY_FOR_PICKUP", "CANCELLED"]),
  READY_FOR_PICKUP: Object.freeze(["COLLECTED", "CANCELLED"]),
  COLLECTED: Object.freeze([]),
  CANCELLED: Object.freeze([]),
});

export function transitionOrder(order, nextStatus, changedAt) {
  const allowedNextStatuses = ALLOWED_TRANSITIONS[order.status] ?? [];

  if (!allowedNextStatuses.includes(nextStatus)) {
    throw new Error(`Invalid transition: ${order.status} -> ${nextStatus}`);
  }

  return Object.freeze({
    ...order,
    status: nextStatus,
    updatedAt: changedAt,
  });
}
{
  "autoMemoryEnabled": false
}
Verify the controlled session

The final check proves that Claude Code can read the fixture from the correct repository. Diagnostics catch installation or settings problems before plan mode becomes part of the experiment.

  • Run the read-only installation and settings diagnostics with:
claude doctor

What does this diagnostic check?

Claude Code inspects its installation and settings without starting an interactive session. A clean result confirms that the project is ready for plan mode.

You should see diagnostic results without an installation or settings problem.

Diagnostics reporting a problem?

Follow the diagnostic guidance shown in the terminal. Restart Visual Studio Code if the problem concerns the installed command or shell path.

After applying the fix, rerun the diagnostic. If it still reports a problem, help me interpret my Claude Code doctor results.

Before you start the controlled session, do you think Claude Code can describe the repository without proposing or applying a change?

  • Start the read-only exploration session by running:
claude --permission-mode plan

Why plan mode?

Plan mode lets Claude Code read files and answer questions while keeping the experiment focused on analysis. The source fixture remains untouched while you inspect how the agent interprets it.

  • Ask Claude Code to inspect the repository by sending:
List the repository files and summarize the existing order behavior without proposing changes.

What does this prompt test?

The prompt limits the response to repository evidence. It also blocks proposals so this session establishes a clean behavioral baseline.

You should see README.md and src/orderService.js named in the response. You should also see the allowed transition checks and frozen updated order described without any file edits.

Your controlled lab is ready. Next, you will give this clean session the vague notification request and watch unsupported assumptions surface.

Expose Hidden Assumptions

Your controlled BrewQueue lab is ready. Claude Code can inspect the repository without editing it.

Now you will use an assumption audit to expose what a plausible plan invents. The request leaves the recipient and channel undefined.

It also says nothing about timing or delivery failure.

In this step, get ready to:
  • Generate a provisional plan from the vague request.
  • Classify every assumption by its evidence.
  • Isolate choices that can change customer-visible behavior or acceptance tests.
Submit the vague request

The baseline prompt blocks clarifying questions on purpose. This gives every unsupported choice a chance to appear in the plan.

Before you send this prompt, predict whether the repository can support every behavioral choice the plan needs.

  • Send this prompt in the current plan mode session:
Read README.md and src/orderService.js. Plan the request exactly as written: “Add notifications when an order status changes.”

Do not ask me questions yet. Do not edit files. Produce a provisional plan, then list every product or technical assumption you made and cite the repository evidence for each one.

What Does This Prompt Test?

  • The reference to README.md anchors the plan in the vague request plus the planning boundary.
  • The reference to src/orderService.js constrains claims about the current transition behavior.
  • The instruction Do not ask me questions yet. forces hidden choices into the provisional plan.
  • The evidence request makes every assumption available for review.
  • Read the provisional plan that Claude returns.
  • Locate the assumption list beneath the plan.
  • Check that each assumption includes a repository citation or an admission that no evidence exists.

You have reached the useful part: a concrete plan with visible claims to audit.

Missing the Assumption List?

If Claude asks questions or skips the audit, resend the baseline prompt unchanged in the same plan-mode session.

If the response still hides its assumptions, help me inspect a Claude Code response that skipped the assumption audit.

Audit assumptions against evidence

The README.md file provides the request plus the planning boundary. The src/orderService.js file provides the existing transition behavior.

How to Classify Each Assumption

  • Use Supported by code when src/orderService.js directly proves the claim.
  • Use Supported by the request when the feature request directly states the behavior.
  • Use Unsupported and product-changing when the choice could change customer-visible behavior or acceptance tests.
  • Use Unsupported but implementation-only when the choice concerns technical mechanics without defining approved product behavior.
  • Review each assumption in Claude's response.
  • Compare its cited evidence with the relevant starter file.
  • Assign one of the four labels to every assumption.

Where Product Choices Hide

  • Trigger status decides which successful transition creates a notification.
  • Recipient decides who receives the notification.
  • Channel decides where the notification appears.
  • Timing decides when notification work begins.
  • Duplicate handling decides whether repeated processing creates another notification.
  • Delivery failure behavior decides what happens after an unsuccessful attempt.
  • Message content decides what the customer sees.
  • Privacy decides which customer data enters the notification.
  • Scope decides which related capabilities stay outside the request.
  • Inspect the plan for an explicit choice in every behavior area above.
  • Mark each choice without repository support in the appropriate unsupported category.
  • Confirm that at least five choices lack support from README.md or src/orderService.js.

Your audit now separates repository-supported facts from request-supported facts. It also separates unsupported product choices from implementation-only choices.

Isolate behavior-changing assumptions

The broad audit includes product decisions plus technical mechanics. One final filter reveals the choices that can alter what customers experience or what acceptance tests require.

Before you ask, predict whether Claude can return a behavioral assumption list with complete repository evidence.

  • Send this follow-up prompt in the same plan-mode session:
Which of your assumptions could change customer-visible behavior or acceptance tests? Return only those assumptions, with no recommendations.

What Does This Filter Reveal?

  • The customer-visible behavior filter removes unrelated implementation mechanics.
  • The acceptance-test filter keeps choices that would change whether the feature passes review.
  • The instruction with no recommendations prevents proposed fixes from hiding the specification gap.
  • Read the filtered response.
  • Check that every item could alter customer-visible behavior or acceptance tests.
  • Verify that every unsupported item lacks approval in README.md or src/orderService.js.

That is the intended shortfall. The plan looks detailed while its behavior-changing choices lack approved evidence.

You caught the core risk: a polished plan can still rest on unapproved behavior. Your starter files remain unchanged inside the read-only session.

Still Seeing Implementation Details?

Exclude any item that only selects storage technology or code structure without changing approved behavior.

If the boundary remains unclear, help me separate behavior-changing assumptions from implementation-only assumptions.

Your audit now makes the gap between evidence and invention visible. Next, you will replace those unsupported choices with explicit product decisions.

Record Product Decisions

Your assumption audit showed that Claude Code can produce a convincing plan while several customer-visible choices still have no approved source.

This step turns those gaps into explicit decisions through a focused interview. The resulting record gives another engineer a reviewable source for the notification behavior.

In this step, get ready to:
  • Guide Claude Code with a behavior-focused interview contract.
  • Approve the notification behavior that affects customers or acceptance tests.
  • Save the reviewed decisions in DECISIONS.md.
Set the interview contract

A structured requirements interview focuses on choices that can change observable behavior. The contract also stops technical preferences from being recorded as approved requirements.

  • Send the interview contract in your existing plan-mode session by pasting this prompt:
We are not implementing yet. Interview me using the AskUserQuestion tool so we can replace unsupported assumptions with approved requirements.

Ask only questions whose answers change customer-visible behavior, acceptance tests, privacy, failure semantics, or scope. Cover the trigger, recipient, channel, timing, duplicate handling, delivery failure, message content, privacy, acceptance scenarios, and out-of-scope work. Ask in small batches. Do not recommend an architecture and do not write code.

When every category has an explicit answer, return a concise Markdown decision record. Do not add decisions I did not make.

Why use an interview contract?

  • The AskUserQuestion tool keeps the exchange focused on explicit answers.
  • The behavioral categories expose choices that could alter customer-visible outcomes.
  • The scope guard keeps architecture choices out of the decision record.

Claude should begin with a small batch of product questions. Each question should connect to behavior or acceptance criteria.

Interview not starting?

  • Confirm that you sent the complete contract in the existing plan-mode session.
  • Ask Claude to begin with the trigger category if it returns a plan instead.
  • Use help me keep the interview focused on product decisions if the response still skips the interview.
Answer the product questions

Each approved answer becomes a behavioral invariant that later plans must preserve. Use the following product-owner choices as Claude asks each category.

  • Approve READY_FOR_PICKUP as the only status that triggers a notification after a successful transition.
  • Identify the recipient as the customer referenced by the order's customerId.
  • Choose the in-app notification channel only.
  • Set notification intent creation immediately after the successful status transition.
  • Limit each order to one ready notification intent.
  • Keep the order in READY_FOR_PICKUP after a delivery failure.

Leave One Boundary Open

The decision record must contain only policies you approve during this interview. Leave the post-queue cancellation behavior unresolved.

  • Keep a failed notification intent eligible for retry.
  • Set the message key to ORDER_READY_FOR_PICKUP.
  • Include the order ID plus the pickup instruction in the message.
  • Exclude the customer's name from the message.
  • Place email, SMS, push notifications, notification preferences, an operator dashboard, retry scheduling, attempt limits, plus delivery vendor selection outside the feature scope.

Turn Decisions Into Tests

Acceptance scenarios make each decision observable. They define the results that a future implementation must produce.

  • Approve one ready notification intent after a successful transition to READY_FOR_PICKUP.
  • Approve no ready notification intent after a transition to another status.
  • Approve no ready notification intent after an invalid transition.
  • Approve no duplicate intent when the same ready outcome is reprocessed.
  • Approve retry eligibility for the failed intent after a delivery failure.
  • Continue the interview until Claude returns the concise decision record requested by the contract.

You should receive a concise Markdown record containing the choices you approved. Unsupported storage or framework choices should remain absent.

Claude added technical choices?

  • Tell Claude to remove any storage mechanism or framework that you did not select.
  • Compare every remaining statement with an answer you explicitly gave.
  • Use help me separate approved behavior from implementation choices if the boundary remains unclear.
Save the reviewed decision record

The conversation now contains approved answers. Saving them in the repository turns that temporary exchange into a reviewable project artifact.

  • In the Visual Studio Code file tree from earlier, create DECISIONS.md inside brewqueue-requirements-lab using the new-file control.
  • Add the goal plus approved behavior by pasting this first section into DECISIONS.md:
# BrewQueue Ready Notification Decisions

## Goal

Tell a customer inside BrewQueue when their order is ready for pickup.

## Approved behavior

- Trigger only after an order successfully reaches `READY_FOR_PICKUP`.
- Send the notification to the customer identified by the order's `customerId`.
- Use the in-app notification channel only.
- Create the notification intent immediately after the successful status transition.
- Create at most one ready notification intent per order.
- A delivery failure must not roll the order back from `READY_FOR_PICKUP`.
- A failed delivery remains eligible for retry.
- Use the message key `ORDER_READY_FOR_PICKUP`.
- Include the order ID and pickup instruction.
- Do not include the customer's name.

What Does This Section Capture?

  • The goal defines the customer outcome in one sentence.
  • The approved behavior records the trigger, recipient, channel, timing, duplicate rule, failure rule, message content, plus privacy boundary.
  • Every statement traces back to an answer from the interview.
  • Save DECISIONS.md.
  • Confirm that the file shows one goal plus ten approved behavior rules.

Missing an approved rule?

  • Compare the file with the first section above.
  • Check that DECISIONS.md is inside brewqueue-requirements-lab.
  • Use help me compare the approved behavior section if a statement still differs.
  • Complete DECISIONS.md by pasting this section on the blank line beneath the final approved behavior rule:
## Acceptance scenarios

- A successful transition to `READY_FOR_PICKUP` creates one ready notification intent.
- A transition to any other status creates no ready notification intent.
- An invalid transition creates no ready notification intent.
- Reprocessing the same ready outcome does not create a duplicate intent.
- A delivery failure leaves the order ready and the intent eligible for retry.

## Out of scope

- Email, SMS, and push notifications
- Notification preference management
- An operator notification dashboard
- A retry schedule, maximum attempt count, or delivery vendor

What Does This Section Add?

  • The acceptance scenarios convert approved behavior into observable outcomes.
  • The out-of-scope list protects the brief from expanding into unapproved channels or delivery choices.
  • The record leaves post-queue cancellation behavior unresolved.
  • Save DECISIONS.md.
  • Confirm that five acceptance scenarios appear above four out-of-scope entries.

Sections running together?

  • Add one blank line before ## Acceptance scenarios if it touches the previous bullet.
  • Keep each heading on its own line.
  • Use help me fix the Markdown structure if the headings still render incorrectly.

✔️ Awesome, I've got everything!

Your reviewed decision record is saved. Check that DECISIONS.md remains inside brewqueue-requirements-lab.

ⓧ I'd like to double check the full code

# BrewQueue Ready Notification Decisions

## Goal

Tell a customer inside BrewQueue when their order is ready for pickup.

## Approved behavior

- Trigger only after an order successfully reaches `READY_FOR_PICKUP`.
- Send the notification to the customer identified by the order's `customerId`.
- Use the in-app notification channel only.
- Create the notification intent immediately after the successful status transition.
- Create at most one ready notification intent per order.
- A delivery failure must not roll the order back from `READY_FOR_PICKUP`.
- A failed delivery remains eligible for retry.
- Use the message key `ORDER_READY_FOR_PICKUP`.
- Include the order ID and pickup instruction.
- Do not include the customer's name.

## Acceptance scenarios

- A successful transition to `READY_FOR_PICKUP` creates one ready notification intent.
- A transition to any other status creates no ready notification intent.
- An invalid transition creates no ready notification intent.
- Reprocessing the same ready outcome does not create a duplicate intent.
- A delivery failure leaves the order ready and the intent eligible for retry.

## Out of scope

- Email, SMS, and push notifications
- Notification preference management
- An operator notification dashboard
- A retry schedule, maximum attempt count, or delivery vendor

What Should Match?

The reference shows the entire reviewed artifact. The starter files remain unchanged.

Before you send the final question, consider this: will Claude preserve the recorded choices or rewrite them?

  • Return to the existing Claude Code plan-mode conversation in the integrated terminal.
  • Test DECISIONS.md by sending this question:
Which behavioral decisions are still unresolved in DECISIONS.md?

What Does This Check Prove?

The question checks whether Claude treats recorded choices as fixed evidence. Genuine gaps should remain visible without changing approved behavior.

You should see only genuine unresolved behavior such as the post-queue cancellation policy. Claude should preserve the choices already recorded in DECISIONS.md.

Claude revised a recorded choice?

  • Ask Claude to quote the relevant statement from DECISIONS.md before naming a gap.
  • Confirm that the approved behavior section matches the full-file reference.
  • Use help me diagnose why Claude is rewriting approved decisions if the response still changes the record.

That is a meaningful shift: your notification request now has an approved behavioral record instead of a collection of guesses. Next, you will encode these decisions as persistent project context for a clean session.

Create Durable Project Context

Your interview turned BrewQueue's vague request into approved product decisions. Those choices now live in DECISIONS.md.

However, later Claude Code sessions cannot rely on the interview conversation. A repository-owned context contract gives each session the same approved vocabulary plus invariants.

This step creates that contract. Git then makes the context visible as part of the project.

In this step, get ready to:
  • Distill the approved decisions into CONTEXT.md.
  • Configure CLAUDE.md to import the durable context.
  • Verify the context artifacts in the Git working tree after closing the authoring session.
Distill the durable context

The reviewed decisions contain the product owner's answers. CONTEXT.md turns those answers into a compact contract that later sessions can load.

Why Repository-Owned Context?

A repository-owned contract stays beside the files it governs. The existing project setting keeps auto memory disabled.

This setup makes the reviewed Markdown files the visible source of product requirements. Conversation history cannot quietly fill the gaps.

  • Ask Claude in the existing plan-mode session to draft a short CONTEXT.md from DECISIONS.md.
  • Require sections for the goal, vocabulary, required behavior, invariants, failure semantics, privacy, acceptance scenarios, plus out-of-scope work.
  • Require the draft to omit code architecture, vendor choices, retry schedules, plus every behavior that was not approved.
  • Review the draft against DECISIONS.md.

Claude should return a concise Markdown draft grounded in the recorded decisions. Any undecided behavior should remain absent or explicitly unspecified.

  • Return to the Explorer sidebar in Visual Studio Code.
  • Use the New File control in the Explorer toolbar to create CONTEXT.md.
  • Add the goal, vocabulary, required behavior, plus invariants by pasting this first block:
# BrewQueue Notification Context

## Goal

BrewQueue gives a customer an in-app notification when their order is ready for pickup.

## Vocabulary

- Order: a record with `id`, `customerId`, `status`, and `updatedAt`.
- Ready transition: a successful transition whose next status is `READY_FOR_PICKUP`.
- Notification intent: the durable request to deliver one in-app message.
- Delivery attempt: an attempt to deliver an existing notification intent.

## Required behavior

- A ready transition creates a notification intent immediately after the status transition succeeds.
- The recipient is the order's `customerId`.
- The channel is in-app only.
- The message key is `ORDER_READY_FOR_PICKUP`.
- The message includes the order ID and pickup instruction.
- The message excludes the customer's name.

## Invariants

- At most one ready notification intent exists per order.
- A transition whose next status is not `READY_FOR_PICKUP` creates no ready notification intent.
- An invalid transition creates no notification intent.

What Does This Context Capture?

  • The vocabulary gives later sessions consistent meanings for orders, ready transitions, notification intents, plus delivery attempts.
  • The required behavior records the approved trigger, recipient, channel, message key, plus message contents.
  • The invariants define conditions that must remain true across every implementation approach.
  • Save CONTEXT.md.
  • Confirm the editor shows BrewQueue Notification Context at the top.

Does the First Half Look Different?

Check that the headings appear once in the same order as the reference. Remove any sentence that introduces a decision missing from DECISIONS.md.

If the structure still differs, help me compare the first half of my context file.

  • Complete CONTEXT.md by adding this block below the final invariant:
## Failure semantics

- A delivery failure does not roll back an order from `READY_FOR_PICKUP`.
- A failed notification intent remains eligible for retry.
- The retry schedule, attempt limit, and delivery mechanism are not specified.

## Privacy

Include only the order identifier, recipient identifier, message key, and pickup instruction needed for the in-app message. Do not include the customer's name.

## Acceptance scenarios

1. `BREWING` to `READY_FOR_PICKUP` creates one ready notification intent.
2. `RECEIVED` to `BREWING` creates no ready notification intent.
3. An invalid transition creates no ready notification intent.
4. Reprocessing the same ready outcome creates no duplicate intent.
5. A delivery failure leaves the order ready and the intent eligible for retry.

## Out of scope

- Email, SMS, and push channels
- Notification preferences
- An operator dashboard
- Delivery vendor selection

What Does This Section Protect?

  • The failure rules preserve the ready order status after a delivery problem.
  • The privacy rule limits message data to the approved identifiers plus pickup instruction.
  • The acceptance scenarios turn each approved behavior into a reviewable outcome.
  • The scope boundary prevents unrelated notification features from entering the brief.
  • Save CONTEXT.md.
  • Confirm the file ends with Delivery vendor selection.

Are Sections Missing or Duplicated?

Confirm the second block begins immediately after the invariants section. Remove any duplicated heading before saving again.

If the sections still do not match, help me find duplicated or missing sections in CONTEXT.md.

✔️ Awesome, I've got everything!

Your durable context contract matches the approved BrewQueue decisions.

ⓧ I'd like to double check the full code

# BrewQueue Notification Context

## Goal

BrewQueue gives a customer an in-app notification when their order is ready for pickup.

## Vocabulary

- Order: a record with `id`, `customerId`, `status`, and `updatedAt`.
- Ready transition: a successful transition whose next status is `READY_FOR_PICKUP`.
- Notification intent: the durable request to deliver one in-app message.
- Delivery attempt: an attempt to deliver an existing notification intent.

## Required behavior

- A ready transition creates a notification intent immediately after the status transition succeeds.
- The recipient is the order's `customerId`.
- The channel is in-app only.
- The message key is `ORDER_READY_FOR_PICKUP`.
- The message includes the order ID and pickup instruction.
- The message excludes the customer's name.

## Invariants

- At most one ready notification intent exists per order.
- A transition whose next status is not `READY_FOR_PICKUP` creates no ready notification intent.
- An invalid transition creates no notification intent.

## Failure semantics

- A delivery failure does not roll back an order from `READY_FOR_PICKUP`.
- A failed notification intent remains eligible for retry.
- The retry schedule, attempt limit, and delivery mechanism are not specified.

## Privacy

Include only the order identifier, recipient identifier, message key, and pickup instruction needed for the in-app message. Do not include the customer's name.

## Acceptance scenarios

1. `BREWING` to `READY_FOR_PICKUP` creates one ready notification intent.
2. `RECEIVED` to `BREWING` creates no ready notification intent.
3. An invalid transition creates no ready notification intent.
4. Reprocessing the same ready outcome creates no duplicate intent.
5. A delivery failure leaves the order ready and the intent eligible for retry.

## Out of scope

- Email, SMS, and push channels
- Notification preferences
- An operator dashboard
- Delivery vendor selection
Add the project instruction file

The domain contract needs a small instruction file that loads it when Claude Code starts. CLAUDE.md also defines how later responses must distinguish evidence from missing decisions.

  • Use the New File control in the Explorer toolbar to create CLAUDE.md.
  • Configure the context import plus evidence workflow by pasting this file:
@CONTEXT.md

# Requirements workflow

- Before proposing implementation, label behavioral statements as `[CONTEXT]`, `[CODE]`, or `[MISSING]`.
- Never convert a `[MISSING]` item into a requirement or recommendation.
- Ask a focused question when a missing decision changes behavior or acceptance tests.
- Do not edit application source unless the learner explicitly asks to implement.

How Does the Workflow Work?

  • The @CONTEXT.md import loads the sibling context file when Claude Code starts.
  • The [CONTEXT] label identifies approved requirements.
  • The [CODE] label identifies facts observed in the source.
  • The [MISSING] label keeps unresolved choices visible.
  • Save CLAUDE.md.
  • Confirm the first line is @CONTEXT.md.

Is the Context Import Missing?

Confirm CLAUDE.md sits beside CONTEXT.md in the brewqueue-requirements-lab folder. Check that the import is the first line.

If the files are in the same folder but the import differs, help me check my CLAUDE.md context import.

✔️ Awesome, I've got everything!

Your project instruction file imports the context contract plus enforces the evidence-label workflow.

ⓧ I'd like to double check the full code

@CONTEXT.md

# Requirements workflow

- Before proposing implementation, label behavioral statements as `[CONTEXT]`, `[CODE]`, or `[MISSING]`.
- Never convert a `[MISSING]` item into a requirement or recommendation.
- Ask a focused question when a missing decision changes behavior or acceptance tests.
- Do not edit application source unless the learner explicitly asks to implement.
Close the authoring session

The durable files are now authored. Closing the current conversation establishes the clean memory boundary needed for the next test.

  • Return to the Claude Code prompt in the integrated terminal.
  • Exit the authoring conversation by entering this command:
/exit

What Does This Command Do?

The command closes the interactive Claude Code session. Your repository files remain in the Visual Studio Code workspace.

You should see the regular terminal prompt again.

Before you run the check, consider whether all three requirements artifacts will appear in the working tree.

  • Inspect the Git working tree by running this command:
git status

What Does This Check Prove?

The command reports files that differ from the repository's recorded state. It provides visible evidence that the requirements artifacts exist outside the closed conversation.

You should see CLAUDE.md plus CONTEXT.md among the working-tree changes.

DECISIONS.md remains present. The starter files also remain unchanged.

Are Context Files Missing?

Confirm the terminal path points to the brewqueue-requirements-lab repository. Check the Explorer sidebar for both new files.

If Git still omits either file, help me find why Git status does not show my context files.

Your requirements now survive beyond the conversation that created them. Next, you will test whether a fresh session can reconstruct the same evidence-backed brief.

Validate a Fresh-Session Brief

You turned the approved BrewQueue decisions into repository-owned context in the previous step. Now a fresh Claude Code session must recover those decisions without relying on the interview conversation.

This clean session is the durability test for your requirements workflow. The resulting brief must distinguish approved context from observed code and unresolved choices.

In this step, get ready to:
  • Confirm that the fresh session loads the project context.
  • Generate a no-code brief with evidence labels.
  • Audit the saved brief without changing application source.
Verify the loaded project memory

A clean session removes the interview conversation from the evidence available to Claude. Your repository files must carry the approved requirements across that boundary.

  • In the Visual Studio Code integrated terminal from earlier, launch a fresh plan-mode session by running this command:
claude --permission-mode plan

What does this command do?

The command starts a new Claude Code session with plan as its permission mode. Claude can inspect the repository while your application source stays unchanged.

You will see a new interactive Claude Code session start inside the brewqueue-requirements-lab repository.

Session does not start?

Confirm the terminal is still inside brewqueue-requirements-lab. If Claude Code reports an account or installation problem, help me diagnose why my fresh plan-mode session will not start.

Before you check, do you expect the new session to find CLAUDE.md without any details from the previous conversation?

  • Check the loaded project memory by entering this command in the plan-mode session:
/context

What does this command show?

The command shows the context loaded into the current Claude Code session. It gives you direct evidence that the repository instruction file crossed the clean-session boundary.

You should see CLAUDE.md under the loaded Memory files. Its imported CONTEXT.md requirements are now available to the fresh session.

  • Test one loaded requirement by sending this prompt:
Restate the ready-notification trigger and its evidence source in one sentence.

What does this prompt test?

The prompt asks Claude to retrieve one approved rule from the loaded project context. The evidence source reveals whether Claude is following the repository contract.

You should see that the trigger occurs after a successful transition to READY_FOR_PICKUP. The sentence should identify project context as the source.

Context file missing?

Confirm that CLAUDE.md sits inside brewqueue-requirements-lab. Confirm its first line is @CONTEXT.md.

If the import still does not load, help me debug why CLAUDE.md is not importing CONTEXT.md.

Set the evidence contract

A useful implementation brief makes the source of each behavioral statement visible. Unsupported technical choices stay explicit gaps until someone approves them.

  • Request the no-code implementation brief by sending this prompt:
Reconstruct a no-code implementation brief for the BrewQueue ready notification feature using only loaded project context and repository code.

Use these evidence labels on every behavioral statement:
- [CONTEXT] for an approved requirement from project context
- [CODE] for an observed fact from the current source
- [MISSING] for a choice the sources do not make

Include goal, current behavior, vocabulary, required flow, invariants, failure semantics, privacy, acceptance scenarios, out of scope, and unresolved decisions. Never turn a [MISSING] item into a recommendation. Do not edit files and do not implement the feature.

How does the evidence contract work?

  • The [CONTEXT] label identifies approved behavior from CONTEXT.md.
  • The [CODE] label identifies behavior observed in src/orderService.js.
  • The [MISSING] label preserves choices that the repository does not make.

You should receive a structured brief that keeps implementation outside the session. Its current-behavior section should describe transitionOrder and ALLOWED_TRANSITIONS as code evidence.

The brief should preserve storage plus retry details as missing decisions. It should not invent a delivery mechanism or retry schedule.

Evidence labels look inconsistent?

Check that every behavioral statement begins with one evidence label. A recommendation attached to [MISSING] breaks the project workflow.

If Claude blends evidence types, help me audit the evidence labels in my BrewQueue brief.

Turn the response into an artifact

The generated Markdown becomes the handoff artifact for a future implementation session. Saving it in the repository makes the evidence contract reviewable.

  • In the Visual Studio Code Explorer sidebar, create IMPLEMENTATION_BRIEF.md inside brewqueue-requirements-lab.

You should see IMPLEMENTATION_BRIEF.md listed beside the existing requirements files.

  • Paste Claude's Markdown response into IMPLEMENTATION_BRIEF.md.
  • Save IMPLEMENTATION_BRIEF.md.

The reference below gives you a precise comparison point for the saved brief.

✔️ Awesome, I've got everything!

Strong result. Your fresh-session brief now separates approved requirements from code evidence and unresolved choices.

ⓧ I'd like to double check the full code

  • Compare IMPLEMENTATION_BRIEF.md with the reference below.
  • Correct every mismatch in IMPLEMENTATION_BRIEF.md.
  • Save IMPLEMENTATION_BRIEF.md.
# BrewQueue Ready Notification Implementation Brief

## Evidence labels

- `[CONTEXT]`: approved behavior loaded from project context
- `[CODE]`: observed behavior in the current repository
- `[MISSING]`: a decision the available sources do not make

## Goal

- `[CONTEXT]` Notify the order's customer inside BrewQueue when the order is ready for pickup.

## Current behavior

- `[CODE]` `transitionOrder` validates the current and next status against `ALLOWED_TRANSITIONS`.
- `[CODE]` A valid transition returns a new frozen order with the next status and supplied timestamp.
- `[CODE]` The current source creates no notification intent and performs no delivery.

## Vocabulary

- `[CONTEXT]` A ready transition is a successful transition whose next status is `READY_FOR_PICKUP`.
- `[CONTEXT]` A notification intent is the durable request to deliver one in-app message.
- `[CONTEXT]` A delivery attempt acts on an existing notification intent.

## Required flow

1. `[CODE]` Validate the requested order status transition.
2. `[CONTEXT]` If the transition fails, create no notification intent.
3. `[CONTEXT]` If the transition succeeds with any status other than `READY_FOR_PICKUP`, create no ready notification intent.
4. `[CONTEXT]` If the transition succeeds with `READY_FOR_PICKUP`, create one in-app notification intent immediately after success.
5. `[CONTEXT]` Address the intent to the order's `customerId` with message key `ORDER_READY_FOR_PICKUP`.

## Invariants

- `[CONTEXT]` At most one ready notification intent exists per order.
- `[CONTEXT]` The message includes the order ID and pickup instruction.
- `[CONTEXT]` The message excludes the customer's name.

## Failure semantics

- `[CONTEXT]` A delivery failure does not roll back the ready order status.
- `[CONTEXT]` A failed intent remains eligible for retry.
- `[MISSING]` The retry schedule and maximum attempt count are not specified.
- `[MISSING]` The storage and delivery mechanism are not specified.

## Acceptance scenarios

1. `[CONTEXT]` `BREWING` to `READY_FOR_PICKUP` creates one ready notification intent.
2. `[CONTEXT]` `RECEIVED` to `BREWING` creates no ready notification intent.
3. `[CONTEXT]` An invalid transition creates no ready notification intent.
4. `[CONTEXT]` Reprocessing the same ready outcome creates no duplicate intent.
5. `[CONTEXT]` A delivery failure leaves the order ready and the intent eligible for retry.

## Privacy

- `[CONTEXT]` Include only the order identifier, recipient identifier, message key, and pickup instruction needed for delivery.
- `[CONTEXT]` Do not include the customer's name.

## Out of scope

- `[CONTEXT]` Email, SMS, push notification, notification preferences, an operator dashboard, and delivery vendor selection are outside this feature.

## Unresolved decisions

- `[MISSING]` Choose a storage mechanism before implementation.
- `[MISSING]` Define the retry schedule and maximum attempt count before implementing delivery retries.
  • Switch back to the plan-mode Claude Code session from earlier.

Before you run the audit, which brief statements do you expect Claude to identify as unsupported by context or code?

  • Audit the brief by sending this prompt:
List every brief statement you cannot support with `[CONTEXT]` or `[CODE]`. Return only those statements. Do not edit files.

What does this audit prove?

The audit forces Claude to separate unsupported choices from approved behavior. A durable brief keeps those gaps visible instead of silently filling them.

You should see only statements labeled [MISSING] from the brief. They should cover storage plus the retry schedule and maximum attempt count.

Supported behavior appears in the audit?

Compare the disputed statement with CONTEXT.md or src/orderService.js. Correct the label only when one of those files provides direct evidence.

If the evidence remains unclear, help me trace this BrewQueue brief statement to its source.

Before the final check, do you expect Git to show any application source changes from this plan-mode session?

  • Ask Claude to inspect the repository state by sending this read-only command:
git status

What does this command confirm?

The command reports the repository working tree without changing it. It lets you confirm that the requirements artifacts exist while application source remains untouched.

You should see IMPLEMENTATION_BRIEF.md among the requirements artifacts. The contents of src/orderService.js should still match the original source fixture.

Secret mission

Catch the Missing Cancellation Rule

Your brief handles ready notifications until a later cancellation puts a queued message in doubt. Test whether Claude Code exposes that gap without choosing for you. Finally, prove that a clean session loads your approved rule.

Clean Up Your Resources

Clean Up Your Resources

The local repository creates no ongoing infrastructure costs because this project provisioned no cloud resources. Decide whether to keep your resources available, pause your work to return later, or delete the repository entirely.

Cost warning

Using Claude Code can count against an existing subscription allowance or Console billing.

  • Choose Pause to avoid additional project interactions while keeping your files.
  • Choose Delete if you no longer need the repository.

Resources you used:

  • Local Git repository brewqueue-requirements-lab, including README.md, src/orderService.js, .claude/settings.json, DECISIONS.md, CONTEXT.md, CLAUDE.md, and IMPLEMENTATION_BRIEF.md.

Keep everything running

No action needed. Choose this if you plan to continue refining the requirements or start an implementation follow-on.

  • Keep the brewqueue-requirements-lab folder on your Mac.
  • Use the evidence-labeled brief as the starting point for future implementation work.
  • Expect future Claude Code interactions to use your existing allowance or Console billing.

Pause - I'll come back to this later

Pausing ends the active Claude Code session while keeping every project file ready for later.

  • Return to the active Claude Code session from earlier.
  • Exit the session by entering /exit.
  • Keep the brewqueue-requirements-lab folder on your Mac.
  • Return to the same folder when you are ready to continue.

Delete - I don't want to use this again

Deleting this folder permanently removes every project file. Your Claude Code installation stays available through your existing account.

  • Exit the Claude Code session by entering /exit.
  • Use Finder to locate the brewqueue-requirements-lab folder.
  • Move the brewqueue-requirements-lab folder to the Trash.
  • Empty the Trash to remove the folder permanently.
  • Confirm that brewqueue-requirements-lab no longer appears in Finder.

Nice Work!

Nice Work!

Excellent work! You turned BrewQueue's vague notification request into a reviewable requirements contract that a clean Claude Code session can reconstruct without changing application source.

You've learned how to:

  • Audit a vague feature request to expose unsupported choices about recipients, channels, timing, duplicates, privacy, failure behavior, message content, and scope.
  • Run a structured requirements interview that replaces assumptions with approved behavior captured in DECISIONS.md.
  • Preserve durable project context in CONTEXT.md and CLAUDE.md. Reconstruct a no-code implementation brief that separates [CONTEXT], [CODE], and [MISSING] evidence.
  • Complete the optional Secret Mission by exposing the missing post-queue cancellation rule. Record the approved suppression policy in CONTEXT.md. Prove that a clean session cites the rule as [CONTEXT].

Ready to quiz yourself?