# Chapter 13: Effective Constraints: Negative-Space Design and Modular Decoupling

## Lesson objectives

- **O1** Can distinguish the scope, owner and handoff between allowed behavior and forbidden behavior (artifact: negative-space constraint table)
  - Evidence: The negative-space constraint table states the scope and owner of both allowed behavior and forbidden behavior
- **O2** Can construct a negative-space constraint table with inclusions, exclusions and human acceptance conditions (artifact: negative-space constraint table)
  - Evidence: The negative-space constraint table contains at least one exclusion, one handoff and one acceptance condition
- **O3** Can constrain a module with allowed and forbidden behavior without prescribing implementation (artifact: negative-space constraint table)
  - Evidence: The artifact gives one module allowed behavior, forbidden behavior, interfaces and a counterexample

## Learning paths

- **Novice**: Chapter transfer task: Can constrain a module with allowed and forbidden behavior without prescribing implementation. Use the diagram's boundary relationship to complete the first evidence item in the negative-space constraint table, then check each owner and decision rule.
- **Experienced**: Apply this task to a current project before reading the explanation: Can constrain a module with allowed and forbidden behavior without prescribing implementation. Submit the negative-space constraint table, then check the relationship type, missing evidence and authority boundary.

## Teaching diagram

- **Required artifact**: negative-space constraint table
- **Diagram kind**: constraint-space
- **Relationship semantics**: The dashed frame is the responsibility boundary; handoffs connect the three elements, and work stops when evidence or authority crosses that boundary.
- **Core concepts**: allowed behavior · forbidden behavior · module interface

![Chapter 13 teaching diagram for the negative-space constraint table](/learning/diagrams/en/chapter-13.svg)

Use boundaries, handoffs and acceptance conditions to test the negative-space constraint table; do not collapse the three elements into one responsibility.

A dashed frame marks the scope of the negative-space constraint table. Three cards represent allowed behavior, forbidden behavior and module interface. Arrows show defined handoffs, not interchangeable responsibilities; crossing the frame or lacking acceptance evidence requires a stop and escalation.

> **Adapted public course.** Concepts, procedures and examples are adapted from the internal textbook. Case sizes, timings, improvement figures and target thresholds are illustrative, not site delivery results or universal standards. Verify tools, platforms and skills in your environment. Prompts do not grant permissions and retry counts do not authorize recovery. Preserve work and verify targets, sharing and external-state effects first.

## Lesson explanation

Chapter 12 established the project blueprint. This chapter adds implementation constraints, starting with the documents' distinct responsibilities:

| Document | Question answered | Content ownership |
|:---|:---|:---|
| CONTEXT.md: project blueprint | What are we building, and why? | Overview, core terminology, tech stack and rationale, data model, API contracts, directory layout, milestones; full structure in Chapter 12, Section 12.2 |
| ARCHITECTURE.md: constraints constitution | Which implementation approaches are unacceptable (how-not-to)? | Prohibitions, red lines, negative-space boundaries, lessons learned |

The blueprint owns project facts; the constitution references the blueprint and limits implementation choices. For example, API fields and return values belong in CONTEXT.md, while "do not bypass authentication" and "do not silently break interface compatibility" belong in ARCHITECTURE.md. Cross-reference both documents. If changed facts touch a red line, resolve the conflict and record the decision before changing the implementation.

### 13.1 Three Essential Documents Beyond the Blueprint: AGENTS.md (AI Code of Conduct), ARCHITECTURE.md (the Architectural Constitution), and CHANGELOG.md (the Voyage Log)

In the age of AI, the value of documentation has undergone a "fusion-level leap." In the past, documentation was "written for humans to read," an "appendage" to the code; now, documentation in the AI era is, first and foremost, "written for machines to read" -- it is the "law" of the codebase and a "generation directive." It has evolved from a passive "manual" into an active "constrainer."

A well-maintained project documentation set is, to an AI, what "Newton's laws" are to the physical world. It is not "advice"; it is a set of foundational rules that must be obeyed and that constitute its worldview. Based on practice, three documents are absolutely essential -- they form the "troika" of the AI constraint system:

Document one: AGENTS.md (or CLAUDE.md, depending on the model you use) -- the AI code of conduct and role definition. It is the AI's "employee handbook," specifying what it may do, what it may not do, and the role it should play. It includes:

- Persona and identity: What role do you want the AI to play? A clear persona activates the AI's knowledge weights in a specific domain;
- Core directives: Global commands, such as "the code must be in English" or "do not say 'I am just a language model'";
- Required document reading: Read technologies and versions in CONTEXT.md and implementation boundaries in ARCHITECTURE.md; do not maintain duplicate lists in the code of conduct;
- Absolute prohibitions: Things the AI is never, under any circumstances, allowed to do;
- Output formatting: How you want the AI to format its answers.

Document two: ARCHITECTURE.md -- the project's constraints constitution. It answers "which implementation approaches are forbidden": absolute prohibitions, red lines that trigger a pause or review, deliberately excluded design space, and lessons learned from failures. Reference CONTEXT.md for the tech stack, data model, API contracts, and directory layout (see Chapter 12, Section 12.2), instead of maintaining four duplicate sections. Lessons record the trigger, failure consequences, corresponding rule, and verification method so prohibitions are traceable.

Document three: CHANGELOG.md -- the log of project evolution and state memory. It is the project's "voyage log," letting the AI "recall" at any moment what has already been done and which stage the project is in. Each entry contains: the date, what was implemented, key decisions, and the next step.

How to use these three documents? Every time you start a new development session, or after running /clear to reset, your first instruction is always:

> "Read root CONTEXT.md, .docs/AGENTS.md (the corresponding CLAUDE.md file in projects using it), .docs/ARCHITECTURE.md, and .docs/CHANGELOG.md. Restate the project goal, applicable red lines, and latest progress; flag conflicts first. According to the log, the next task is the login page. Locate the file using the blueprint's directory layout before starting."

This instruction acts like a "boot disk," instantly loading into the AI's mind all of your project's core rules, its full architecture, and the latest progress. It turns a "general-purpose" large model into a "domain expert" dedicated to your project.

> For full templates, see Appendix D, "Project Documentation Templates."

### 13.2 Negative-Space Design: First Define What Is Forbidden, Then Let It Write Code

In art and design there is an important concept called "negative space" -- the empty areas around and between the subject objects. A mediocre painter sees only the apple he intends to paint; a master simultaneously sees the apple itself and the shape of the surrounding sky "carved out" by the apple's contour. The master knows that by carefully sculpting the "emptiness," the subject becomes more prominent, more powerful, and more sharply defined.

This idea transfers perfectly to the domain of AI programming, forming the most refined art of constraint: negative-space design.

In traditional AI programming -- call it "positive-space design" -- we rack our brains to tell the AI what to do in ever more detailed and precise language. Negative-space design is a fundamentally different, higher-dimensional approach: we stop obsessing over depicting the apple itself, and instead sculpt the "emptiness" around it. With a series of clear, merciless "forbidden" directives, we exclude a set of known-wrong possibilities. In the end, constraint-satisfying candidate "apples" emerge as the shapes left over after exclusion -- but note that exclusion can only rule out known bad paths; it cannot guarantee the remaining candidates are the single absolutely correct answer, which still requires acceptance review.

Why is "prohibition" more effective?

The core of a large AI model is an engine of probabilistic possibility, not an engine of logical certainty. When you give it an "implementation instruction" ("write a function to handle user-uploaded images"), you are effectively throwing it into a boundless "ocean of possibilities": it could use the Pillow library, or OpenCV; it could save to memory first, or to a temporary file first; it could support PNG and JPG, or perhaps forget to support GIF... The AI picks the highest-probability path according to its training data, and that path will most likely be incompatible with your project's existing architecture, conventions, and hidden constraints. And so you fall into an endless "correction loop."

Now switch to "negative-space" mode. Instead of teaching it how to swim, we start building dams in the ocean:

> "I want you to handle user-uploaded images. However:
> - You must not use OpenCV or any image-processing library other than Pillow;
> - You must not read the entire file into memory at once; you must use streaming or write to a temporary file in chunks;
> - You must not hardcode the list of supported file formats inside the function; it must be read from the global configuration file config.py;
> - You must not return binary data from the function; it must return the absolute path of the processed file."

We did not teach AI every step. Four prohibition directives instead exclude a set of known unacceptable paths and steer the candidate space toward the current architecture. Constraints cannot create one uniquely and absolutely correct solution by themselves: omitted requirements, conflicting rules, and false premises can still make the remaining candidates fail. Generated output must therefore pass tests, review, and operational feedback.

The four core values of "prohibition directives":

1. They drastically reduce the AI's "choice paralysis": The AI does not truly "think"; it searches an enormous vector space for the most similar patterns. More choices only increase the probability of it matching the wrong pattern;
2. They make your "tacit knowledge" explicit: For example, "never introduce a library with C++ bindings, because that makes deployment unbearably painful" -- this hard-won lesson becomes remarkably simple as a prohibition directive: "You must never introduce any Python library that requires compiling C++ extensions";
3. They greatly reduce your "review cost": Reviewing "whether it was implemented" requires understanding all the logic; reviewing "whether a prohibition was violated" becomes a mechanical checklist check -- "Did it use OpenCV? No. Did it hardcode anything? No.";
4. They are the ultimate weapon against the "spiral of entropy": AI is inherently inclined to patch things, and prohibition directives are the firewall against that behavior. Weak directive (implementation): "Please add caching to this function." (The AI might just add a global dictionary inside the function as the cache, causing a memory leak); Strong directive (prohibition): "Please add caching to this function. You must not implement any caching logic inside the function itself. You must use Python's functools.lru_cache decorator."

From now on, shift your thinking: Before asking the AI anything, do not rush to think "what should I make it do." Instead, spend a minute asking yourself: "To get this feature implemented the right way, what must I forbid it from doing?" This question is the watershed between being a mere AI user and becoming an AI master.

Drawing the capability boundary: red lines + paths.

An effective constraint architect knows how to precisely identify the system's "lifelines" and build layered defenses around them. This process is called "drawing the capability boundary."

- Step one: identify the "absolute red lines" -- the core principles that, once touched or misunderstood by the AI, cause architectural collapse, security holes, or maintenance hell. Think along four dimensions: the "backbone" of the architecture (e.g., "no module in the UI layer may directly import modules from the data-access layer"), the "lifeline" of security (e.g., "never concatenate any variable directly into a SQL query string"), the "bottleneck" of performance (e.g., "never execute database queries or API calls inside loops -- the N+1 problem"), and the "contract" of team collaboration (e.g., "never commit any code that fails ESLint and Prettier checks").
- Step two: define the "core implementation paths" -- once the red lines are drawn, the remaining territory is where the AI can be safely unleashed. Here the constraints shift from "never do X" to finer-grained guidance on "how it should be done," still using the negative-space approach: by eliminating suboptimal options, the AI is steered toward the optimal one.

For example, "implement a frontend search box with debouncing": draw the red lines ("You must not hand-roll debounce logic. You must not install any utility library other than lodash-es") plus guide the path ("You must use the debounce function from the lodash-es library, with a 300-millisecond delay"). The combination of "red lines + paths" both guarantees architectural stability and fully exploits the AI's coding efficiency at the concrete implementation level.

Using "elimination" to guide the AI into the right region -- the "constraint funnel" model:

Imagine a giant funnel: the widest opening is the AI's "space of infinite possibilities"; the narrowest outlet is the set of constraint-satisfying candidate solutions. Every prohibition directive adds another filter screen to the funnel's wall.

- First filter: global constraints (the document layer) -- the broadest filtering, formed by AGENTS.md and ARCHITECTURE.md;
- Second filter: task-level constraints (the initial instruction) -- "local" prohibition directives targeting a specific task;
- Third filter: interactive fine-tuning (dynamic constraints in dialogue) -- after the AI delivers its first version of the code, add finer filter screens through conversation;
- Fourth filter: final acceptance (tests and automation) -- the last and most objective filter screen.

Through this "constraint funnel" model, we decompose a complex, open-ended "creation" task into a series of simple, closed "elimination" tasks. We no longer expect the AI to nail it in one shot; instead we enjoy the process of sculpting a rough stone into a fine work of art by progressively tightening the constraints.

### 13.3 Writing Constraint Directives the AI Can Understand and Dare Not Defy (Five Principles)

Writing constraint directives for an AI is an art, fundamentally different from writing documentation for humans. Humans can grasp vagueness, subtlety, and implication, while the AI needs precise, unambiguous, code-like language. Here are five core principles:

Principle one: use imperative sentences and modal verbs.

Do not use a suggestive or descriptive tone; use a commanding tone. Words like Must, Must not, Always, Never, and Do not greatly increase the weight of the instruction inside the AI model.

- Vague (weak constraint): "It would be good if we use named exports."
- Precise (strong constraint): "You must always use named exports (export const ...). Do not use default exports (export default)."

Principle two: provide positive and negative examples (Dos and Don'ts).

Saying only "don't do X" is not enough; it is best to also provide an example of the correct way to do it. This helps the AI learn and match the pattern you want more quickly.

<!-- code-example:chapter-13-E1 mode:reference -->
> **Example type: reference.** Reference fragment; it is not guaranteed to run alone. Adapt it to the lesson context, project versions and real interfaces, then validate with observed output.
```text
❌ Vague: "Avoid complex logic in components."
✅ Precise: "Prohibition: Do not write business logic directly in React components.
  Don't (Bad Practice):
  // In MyComponent.jsx
  function handleClick() {
    const complexData = someData.map(...).filter(...);
  }
  Do (Good Practice):
  // In useMyLogic.js (Hook)
  export function useMyLogic() {
    const processData = () => { ... };
    return { processData };
  }
  // In MyComponent.jsx
  const { processData } = useMyLogic();
```

Principle three: quantify, do not qualify.

Avoid subjective, unquantifiable words like "good," "fast," or "simple." Define things with numbers and concrete criteria wherever possible.

- Vague: "Functions should not be too long."
- Precise: "Constraint: No single function should exceed 50 lines of code. If it does, you must suggest refactoring it into smaller helper functions."
- Vague: "API response should be fast."
- Precise: "Performance Budget: All P1 API endpoints must have a median response time under 100ms."

Principle four: cite "authoritative sources."

When a rule you set is based on an industry standard or best practice, say so explicitly. This increases the "authority" of the constraint.

- Vague: "API should be well-designed."
- Precise: "API Design: All APIs must adhere to the RESTful principles. Specifically, use correct HTTP verbs (GET, POST, PUT, DELETE) for corresponding actions and use HTTP status codes to indicate outcomes."

Principle five: use scenario-triggered rules (When-Then Rules).

For complex logic, use "if... then..." constructions to define scenario-triggered automated behavior.

<!-- code-example:chapter-13-E2 mode:reference -->
> **Example type: reference.** Reference fragment; it is not guaranteed to run alone. Adapt it to the lesson context, project versions and real interfaces, then validate with observed output.
```text
Error Handling Policy:
- When an API call fails due to a network error, then you must implement an
  exponential backoff retry mechanism (3 retries).
- When an API call returns a 401 Unauthorized status, then you must immediately
  redirect the user to the login page.
- When any other server error (5xx) occurs, then you must display a generic
  error message to the user and log the detailed error to the console.
```

Through these five principles, you can forge your project documentation from a vague "guidance manual" into a precise "body of law." This is what "nailing down every word" truly means -- you trade the "rigidity" and "unquestionability" of documents for the "stability" and "high predictability" of AI execution.

### 13.4 Modular Decoupling: the Main-Flow/Capabilities Pattern, So the AI Faces Only One Small Problem at a Time

When a project swells and the codebase becomes a behemoth of hundreds of files and tens of thousands of lines of code, even perfect documentation will not stop the AI from showing signs of "confusion," "forgetfulness," or even "derangement" when confronting this "monster." It might reference a completely unrelated module during a seemingly simple change; or, while refactoring one function, forget that it is also called in some obscure corner five files away.

The root of the problem is not that our instructions are unclear, but that we have crammed far more information into the AI's mind than its "cognitive bandwidth" can hold. Through careful physical code-structure design, we must break a huge, intimidating codebase into a series of independent "small problems" the AI can easily understand and handle. We must decouple not only the "code" but also "the AI's attention."

Why does the AI "go mad" in a huge codebase? Three root causes:

- Root cause one: the "flattening curse" of context. When a human engineer reads a large project, the brain automatically builds a hierarchical, weighted mental model -- knowing which modules are core and which are peripheral. The AI has no such ability: to it, all code context is a flat, undifferentiated sequence of tokens. This leads to scattered attention and false associations -- because the string "primary-color" appears in both a CSS file and a database configuration file, the AI might "helpfully" change the database configuration too, leaving the backend unable to connect to the database.
- Root cause two: the "cognitive black hole" of implicit dependencies. One module mutates another module's state through a global variable; a function depends on some environment variable holding a particular value at a particular moment -- human developers remember these "minefields" through project experience, but the AI knows nothing about them. When it modifies one module, it cannot predict how the change will ripple outward through invisible channels.
- Root cause three: the "physical ceiling" of token limits. Every large model has a token limit on its context window. When total project code exceeds that limit, you are forced to manually pick "relevant" files -- a process that is itself error-prone and misleading to the AI.

Conclusion: the fundamental way to fight AI "madness" is not to train a smarter AI, nor to hope for an infinitely long context window, but to start from the code architecture itself -- transforming the huge, flat, implicitly entangled "cognitive swamp" into an orderly world composed of many small, independent, cleanly interfaced "cognitive building blocks."

The most common mistake in modular decoupling is dividing by "technical type" or "feature page" -- putting all API requests in one folder and all UI components in another. A deeper decoupling pattern, one that better matches the AI's mental model, is called the "Main Flow / Capabilities" pattern (Capability-Driven Decoupling).

Its core idea: split a complex business feature into an extremely concise, stable "Main Flow," plus a set of pluggable, independent "Capabilities."

- Main Flow: responsible for one thing only -- orchestrating the various capabilities, in the most high-level language closest to business terms, to complete a full business loop. The main flow itself contains no implementation detail; it should be extremely stable and rarely change.
- Capabilities: each "capability" is an independent module encapsulating one concrete technical implementation -- "send a request to the API," "store data locally," "parse a PDF file," "show a notification popup." These capability modules are replaceable, independently testable, and can be independently modified by the AI.

A vivid analogy: imagine you are directing a film shoot. The main flow (the director's job) is the screenplay -- "Scene one: the protagonist enters, looking grave. Scene two: an explosion happens. Scene three: the protagonist finds a clue in the wreckage." The screenplay cares only about "what (What)" happens, not "how (How)" it happens. The capabilities (the various departments) -- lighting, camera, props -- are independent, dispatchable units of capability. If the lighting department has a problem, you only need to send the lighting department's "sub-agent" (an AI instance) to fix the lighting code; you do not need to halt the entire crew.

The revolutionary significance of modular decoupling for AI collaboration: when an AI faces only the "lighting department" module, its context is clean and focused; when it faces the entire "crew," its attention is diluted and contaminated. A highly cohesive, loosely coupled, "AI-friendly" project structure is the infrastructure that lets the AI face only one small problem at a time.

### 13.5 Restructure an Existing Project into an AI-Friendly Layout in 30 Minutes

Goal: without changing business logic, adjust the code structure to turn the existing project into one that is friendlier to AI and amenable to independent collaboration.

Guided steps:

1. Inventory (5 minutes): list all modules in the project, with a one-sentence description of each module's responsibility. Identify which are "main flows" and which are "capabilities."
2. Draw boundaries (5 minutes): find implicit dependencies -- global variables, shared state, implicit event communication -- and make them explicit (extract them into separate modules or clear interfaces).
3. Split (10 minutes): organize directories along the "Main Flow / Capabilities" pattern. Each capability module is self-contained: its own type definitions, utility functions, and state management.
4. Write documentation (10 minutes): for each module, write a short README or comment block -- what it does, its inputs and outputs, and dependencies. Update directories and interfaces in CONTEXT.md, forbidden module crossings in ARCHITECTURE.md, and direct readers to both from AGENTS.md.

Acceptance checks (before/after comparison):

- Has the number of modules increased while each module's line count dropped sharply?
- Have inter-module dependencies been made explicit (through imports rather than global variables)?
- Can unit tests now be written for each module independently?
- Can the AI complete a modification task for a module while reading only that module's documentation?

> For the complete operation card of the 30-minute restructuring, see Appendix D.

### [Template] A Ready-to-Use Project Documentation Skeleton

> First complete the seven-part CONTEXT.md blueprint from Chapter 12, Section 12.2, then add these three companion documents. Fill and verify skeleton placeholders before implementation. Appendix D provides additional material; document responsibilities follow the division established here and in Chapter 12.

Project skeleton (directory structure):

<!-- code-example:chapter-13-E3 mode:reference -->
> **Example type: reference.** Reference fragment; it is not guaranteed to run alone. Adapt it to the lesson context, project versions and real interfaces, then validate with observed output.
```text
project-root/
├── .docs/
│   ├── AGENTS.md          # AI code of conduct (or CLAUDE.md, depending on the model)
│   ├── ARCHITECTURE.md    # architectural constitution
│   └── CHANGELOG.md       # voyage log
├── CONTEXT.md             # project blueprint
├── REQUIREMENTS.md        # requirements list and divergence record
├── src/
└── tests/
```

ARCHITECTURE.md minimal template (stored in .docs/ according to the skeleton above):

<!-- code-example:chapter-13-E4 mode:reference -->
> **Example type: reference.** Reference fragment; it is not guaranteed to run alone. Adapt it to the lesson context, project versions and real interfaces, then validate with observed output.
```markdown
## Constraints Constitution: {project name}

For goals, terminology, stack, data model, API contracts, directories, and milestones,
see the project blueprint. This file owns implementation boundaries only.
Root CONTEXT.md must link back here: .docs/ARCHITECTURE.md.

## Absolute Prohibitions
- Never call the data-access layer directly from the UI layer
- Do not add dependencies outside the CONTEXT.md tech stack
- Do not silently change blueprint fields or API contracts

## Red Lines and Triggered Actions
- No single file over 300 lines; propose a split before exceeding this limit
- Before touching {list of core modules}, stop to confirm impact and authorization
- Resolve and record conflicts with the blueprint; do not ignore rules independently

## Negative Space: Explicitly Excluded This Phase
- Exclude {approach or scope}; rationale: {current limits and trade-offs}
- Reassessment conditions: {changes that would justify reopening the discussion}

## Lessons Learned
| Trigger | Failure Consequences | Corresponding Rule | Verification Method |
|:---|:---|:---|:---|
| {reviewed situation} | {traceable consequences} | {prohibition or red line} | {test or review evidence} |
```

AGENTS.md minimal template (write the "don'ts" first, then the "dos"):

<!-- code-example:chapter-13-E5 mode:reference -->
> **Example type: reference.** Reference fragment; it is not guaranteed to run alone. Adapt it to the lesson context, project versions and real interfaces, then validate with observed output.
```markdown
## AI Code of Conduct

## Must (Must / Always)
- Read ../CONTEXT.md and ARCHITECTURE.md in this directory before starting work
- Self-test each feature before delivery

## Constraint Enforcement (Must not / Never)
- Never bypass ARCHITECTURE.md prohibitions, red lines, or review requirements
- Report document conflicts first; do not rewrite rules just to accommodate code
```

CHANGELOG.md minimal template:

<!-- code-example:chapter-13-E6 mode:reference -->
> **Example type: reference.** Reference fragment; it is not guaranteed to run alone. Adapt it to the lesson context, project versions and real interfaces, then validate with observed output.
```markdown
## {YYYY-MM-DD}
- Implemented: {completed feature/fix}
- Decision: {important decision}
- Next Step: {next task}
```

> Acceptance check: once the skeleton is in place, have AI read CONTEXT.md and the three companion documents, then restate the next step, applicable red lines, and their sources. Check that the blueprint and constitution reference each other and each fact has one maintained location. Correct restatement shows aligned context; tests and review must still verify code compliance.

---

<!-- cognitive-load-checkpoint -->
## Pause and organise: complete the minimum loop

First write one relationship between allowed behavior and forbidden behavior, then place it in the negative-space constraint table. Confirm that this step has an input, decision and evidence before adding module interface; do not start the independent exercise until the three are connected.

## Independent exercise

Use fictional or authorized deidentified material. Answer independently before revealing the reference. Save `chapter-13.md` with versions, decisions, evidence and gaps.

Write three negative-space constraints and place workflow, architectural boundaries and delivered changes in the appropriate documents. Explain dependency direction.

<!-- chapter-artifact-requirement -->
### Required chapter artifact: negative-space constraint table

The submission for this independent exercise must contain the evidence below. The existing prompts supply content but do not replace these acceptance items.

- O1: The negative-space constraint table states the scope and owner of both allowed behavior and forbidden behavior
- O2: The negative-space constraint table contains at least one exclusion, one handoff and one acceptance condition
- O3: The artifact gives one module allowed behavior, forbidden behavior, interfaces and a counterexample

<details>
<summary>Reveal reference feedback (answer first)</summary>

## Reference feedback

AGENTS records working and verification practices; ARCHITECTURE records lasting boundaries such as no UI dependency or raw sensitive logging; CHANGELOG records delivered changes. CONTEXT owns facts. Checkable restrictions matter; prompts do not enforce tool permissions.

### Self-review and next steps

Check whether your decision is explicit, evidence reproducible and unknowns honestly recorded. The reference illustrates one defensible approach, not a unique answer. Seek peer review for alternatives with equivalent evidence. Mark unsupported parts unfinished and revisit the corresponding step.

</details>

## Sources and boundaries

Registered sources support only the external claims used here. The negative-space constraint table, example numbers and exercise scenario are internal instructional design and require project-specific validation.

- [OWASP risks for LLM applications](https://genai.owasp.org/llm-top-10/) — OWASP Foundation, 2026-09-17. Model output, sensitive information, tool permissions and human control require explicit risk boundaries.
