Module 8: Capstone Project

Final Phase: Delivery and Retrospective

Final Phase: Delivery and Retrospective

Capsule overview

You've completed the three phases of the project: code review, debugging, and correction. Now comes the part that closes the learning loop: organizing your delivery and writing the retrospective. The retrospective isn't a bureaucratic add-on — it's where the learning consolidates. The best developers don't just fix bugs, they reflect on their process to be better next time.

This capsule gives you the exact checklist of what you must deliver, the 100-point self-assessment rubric, the guiding questions for the retrospective, and examples of excellent deliveries so you can calibrate your work.


Delivery Checklist

Your delivery must contain exactly these 4 documents:

Document 1: Findings Document

# TaskFlow API — Findings Document

## Reviewer Information
- Name: [Your name]
- Date: [Date]
- Total time invested: [Hours]
  - Static code review: [Time]
  - Debugging: [Time]
  - Correction: [Time]
  - Documentation: [Time]

## Executive Summary
[2-3 sentences on the state of the codebase]

## Findings

| # | Severity | Category | File | Line(s) | Description | Requirement | Impact |
|---|-----------|-----------|---------|----------|-------------|-----------|---------|
| 1 | | | | | | | |
| 2 | | | | | | | |
[...all the findings...]

## Statistics
| Severity | Found | Total expected |
|-----------|-------------|----------------|
| Critical  |             | 3-4            |
| High      |             | 4-5            |
| Medium    |             | 5-6            |
| Low       |             | 3-4            |
| **Total** |             | **15-20**      |

## Process Notes
[Observations about the codebase, the review experience, 
what was easy and what was hard]

Document 2: Corrected Code

The complete codebase with all the corrections applied. It can be:

  • A directory with all the corrected files
  • A file with the corrected code sections and the lines that changed

Each corrected file must include at the top:

# CORRECTIONS IN THIS FILE:
# - [Line X]: [Brief description of the fix]
# - [Line Y]: [Brief description of the fix]

Document 3: Justifications

# Correction Justifications — TaskFlow API

## Fix #1: [Title]
**Finding:** #[number]
**Severity:** [level]
**File:** [name]

### What I changed
[Description of the change]

### Why it was incorrect
[Requirement violated and explanation]

### Why my fix is correct
[Explanation and verification]

### Regenerate/edit decision
[Decision and justification]

---
[Repeat for each fix]

Document 4: Retrospective

A 300-500 word document. Detailed format later in this capsule.


Self-assessment Rubric (100 points)

Section 1: Findings (40 points)

Number of findings (20 points)

Findings foundPoints
16-18 of 1820
14-15 of 1817
12-13 of 1814
10-11 of 1811
8-9 of 188
< 8 of 185

Correct severity (10 points)

CriterionPoints
Correct severity on 90%+ of findings10
Correct severity on 75-89%7
Correct severity on 60-74%5
Correct severity on less than 60%2

Guide for assessing severity:

  • Are the security holes marked as Critical?
  • Are the business logic problems marked as High?
  • Are the edge cases marked as Medium?
  • Are the hallucinations with no direct impact marked as Low?

Documentation quality (10 points)

CriterionPoints
Every finding has: clear description, file, line, impact, requirement violated10
Most have all the information, some incomplete7
Partial information on most findings4
Findings with only a description, no context2

Section 2: Corrections (30 points)

Correct corrections (15 points)

CriterionPoints
Every Critical and High fix is correct15
Most Critical and High are correct, some partial12
Some fixes are correct, others incorrect or partial8
Most fixes are incorrect or not implemented4

How to assess whether a fix is "correct":

  • ✅ It solves the identified problem
  • ✅ It doesn't introduce new problems
  • ✅ It complies with the functional requirement
  • ✅ It passes runtime verification

Justifications (10 points)

CriterionPoints
Every fix has a complete justification referencing requirements10
Most have a justification, some superficial7
Justifications present but generic4
No justifications, or only "I fixed it"1

Regenerate/edit decisions (5 points)

CriterionPoints
Every fix documents the decision with reasonable justification5
Most document the decision3
Few decisions documented1

Section 3: Process (20 points)

Systematic process (10 points)

CriterionPoints
Followed the phases in order (review → debug → fix), documenting each step10
Followed a reasonable process, partial documentation7
Ad-hoc process but completed the tasks4
No evidence of a systematic process1

Evidence of a systematic process:

  • Did you complete the code review before starting to fix?
  • Did you document the debugging steps?
  • Did you prioritize the fixes by severity?
  • Did you verify each correction?

Tool usage (10 points)

CriterionPoints
Strategic use of Claude Code: specific questions, verification of answers, documentation of usage10
Good use of Claude Code, partial verification7
Use of Claude Code without verification or without documenting4
Didn't use Claude Code, or used it indiscriminately2

Evidence of good tool usage:

  • Are the questions to Claude Code specific and verifiable?
  • Did you verify Claude Code's answers before accepting them?
  • Did you document when Claude Code helped and when it didn't?
  • Did you use manual debugging when it was more appropriate?

Section 4: Retrospective (10 points)

CriterionPoints
Reflective, specific, with concrete and actionable examples10
Reflective and with some specific insights7
Present but generic ("I learned a lot", "it was hard")4
Superficial, short, or absent1

A 10/10 retrospective has:

  • Specific examples of what was hard and why
  • Identification of which mental model or technique was most useful
  • Honest reflection on mistakes or things you'd do differently
  • Concrete actions to improve your process in the future

Final Grading Table

RangeGradeDescription
90-100ExcellentDemonstrates professional mastery of the complete process
75-89GoodSolid in most areas, with room to improve
60-74AcceptableCompleted the project but with significant gaps
< 60Needs reinforcementReview earlier modules and try again

Guide for the Retrospective

Why the retrospective matters

The retrospective isn't a report of what you did. It's a reflection on how you did it and what you learned from the process. The best developers don't just solve problems — they improve their problem-solving process. The retrospective is where that happens.

Guiding questions

Answer these questions in your retrospective (300-500 words). You don't need to answer all of them, but your retrospective must cover at least 4 of these topics:

About what you found

1. What was the hardest thing to find? Why?

Reflect on the findings that cost you the most. Was it a subtle hallucination? A logic error that looked correct? An edge case that didn't occur to you to test? Understanding why something was hard helps you improve.

2. What surprised you to find?

Was there a problem you didn't expect? Did the code look fine on the first read but hide something? Did you find something that isn't in the categories you anticipated?

3. Were there false positives? Did you report something as a problem that turned out not to be one?

False positives are normal and valuable. If you thought something was a bug and later discovered it wasn't, reflect on why you got confused.

About your process

4. Which mental model helped you most?

Of the three mental models from Module 2 (Managing an Intern, Circuit Breaker, Trust Calibration), which one did you apply most? Which was most useful in practice? Is there one you didn't apply?

5. Was your review process effective? What would you change?

Did you find the problems in the first passes or did you need to go back? Was the review order (security → logic → edge cases → quality) useful? Did you spend too much time on one category and too little on another?

6. How did you use Claude Code? Was it effective?

Did you ask it specific questions? Did you verify its answers? Were there moments where it was very useful and others where it didn't help? Would you use it differently next time?

About what you'll change

7. What would you do differently next time?

If you had to do the same project again, what would you change in your process? Would you start somewhere else? Would you use different tools? Would you focus more on some category?

8. How will this change your daily workflow?

This guide taught you to review AI-generated code. How will you apply this in your daily work? Will you adopt the checklist? Will you change your level of trust in AI code? Is there a specific practice you'll incorporate?

Retrospective format

# Retrospective — TaskFlow API Capstone Project

## Date: [date]
## Total project time: [hours]

---

[300-500 words answering the guiding questions.
Use first person. Be specific. Give examples.
You don't need subheadings — it can be flowing text.]

---

## Concrete actions for my workflow

1. [Specific action you'll take in your daily work]
2. [Specific action you'll take in your daily work]
3. [Specific action you'll take in your daily work]

Example of an Excellent Delivery

Example Findings Document (excerpt)

# TaskFlow API — Findings Document

## Reviewer Information
- Name: María García
- Date: March 15, 2026
- Total time: 3.5 hours
  - Code review: 1.5 hrs
  - Debugging: 45 min
  - Correction: 50 min
  - Documentation: 25 min

## Executive Summary

The TaskFlow API codebase implements the basic 
task CRUD and authentication functionality, but it contains 
multiple critical security vulnerabilities 
(SQL injection, plaintext password, hardcoded secret) 
that make it unsafe for production. It also has 
business logic problems that violate 6 of the 
functional requirements, and edge cases that cause crashes 
with legitimate inputs. It requires significant corrections 
before any deploy.

## Findings

| # | Severity | Category | File | Line(s) | Description | Requirement | Impact |
|---|-----------|-----------|---------|----------|-------------|-----------|---------|
| 1 | Critical | Security | config.py | 12 | JWT_SECRET_KEY has the hardcoded fallback "super-secret-key-taskflow-2026". Anyone with access to the code can forge valid tokens. | RF-02.3, RF-06.1 | Total compromise of authentication |
| 2 | Critical | Security | routes/auth.py | 18-20 | register() inserts user.password directly without hashing. Passwords are stored in plain text. | RF-01.2 | Exposure of every password if the DB is compromised |
| 3 | Critical | Security | routes/users.py | 28-30 | search_users() uses an f-string to build the SQL query: f"...WHERE name LIKE '%{query}%'". Vulnerable to SQL injection. | RF-06.2 | An attacker can extract all the data from the DB |
| 4 | Critical | Security | routes/users.py | 25-30 | search_users() doesn't require authentication. Anyone can search users without being logged in. | RF-02.4 | Exposure of user data without authorization |
| 5 | High | Logic | services/task_service.py | 98-101 | delete_task() runs DELETE FROM (hard delete) instead of UPDATE status = 'deleted' (soft delete). | RF-03.6 | Data lost permanently, impossible to recover |
| 6 | High | Logic | services/task_service.py | 23-28 | get_task_by_id() doesn't filter by user_id. Any authenticated user can see any task. | RF-03.7, RF-05.6 | Exposure of data between users |
| 7 | High | Logic | services/task_service.py | 107-120 | get_user_stats() includes deleted tasks in the count and percentage. | RF-04.2 | Incorrect statistics |
| 8 | High | Validation | models.py | 14-16 | validate_password() accepts passwords of 4+ characters. RF-01.4 requires 8 minimum. | RF-01.4 | Weak passwords accepted |
| 9 | Medium | Security | services/task_service.py | 47-51 | get_tasks() uses f-strings to insert status and priority into the SQL query. | RF-06.2 | SQL injection through filters |
| 10 | Medium | Edge Case | services/task_service.py | 118 | completion_percentage divides by total without checking that it isn't 0. ZeroDivisionError for users with no tasks. | RF-04.1 | Endpoint crash with a 500 error |
| 11 | Medium | Edge Case | services/task_service.py | 55 | offset = page * size. For page=1, offset=10, skipping the entire first page. | RF-03.2 | The first page never shows results |
| 12 | Medium | Validation | models.py | 37-40 | validate_title() accepts titles of 1+ character. RF-05.1 requires 3-100. | RF-05.1 | Invalid titles accepted |
| 13 | Medium | Validation | models.py | — | There's no validation of priority or status against the allowed values. | RF-05.2, RF-05.3 | Arbitrary values accepted |
| 14 | Medium | Edge Case | routes/tasks.py | 30 | page=Query(default=1, ge=0) accepts page=0. | RF-05.4 | Pagination with invalid values |
| 15 | Low | Hallucination | main.py | 3 | from pydantic_settings import BaseSettings. The pydantic-settings package isn't in requirements.txt and isn't installed. | — | ModuleNotFoundError at startup |
| 16 | Low | Hallucination | services/auth_service.py | 7 | from bcrypt import verify_hash. The verify_hash function doesn't exist in bcrypt. The real functions are hashpw, gensalt, checkpw, kdf. | — | ImportError at startup |
| 17 | Low | Hallucination | services/task_service.py | 62 | cursor.fetchall(as_dict=True). sqlite3's fetchall() doesn't accept parameters. | — | TypeError when listing tasks |
| 18 | Low | Security | main.py | 16-21 | CORS allows every origin (allow_origins=["*"]). It isn't a functionality problem but it's bad practice for production. | — | Potential CSRF in production |

## Statistics
| Severity | Found | Total expected |
|-----------|-------------|----------------|
| Critical  | 4           | 3-4            |
| High      | 4           | 4-5            |
| Medium    | 6           | 5-6            |
| Low       | 4           | 3-4            |
| **Total** | **18**      | **15-20**      |

Example of an Excellent Retrospective

# Retrospective — TaskFlow API Capstone Project

## Date: March 15, 2026
## Total time: 3.5 hours

---

The hardest thing to find was the password stored 
in plain text in routes/auth.py. It sounds contradictory 
because it should be obvious, but the file imports 
hash_password from auth_service.py — the function exists 
and it works. The problem is that register() never calls it. 
I went through that file twice before noticing that user.password 
is passed directly to the INSERT with no transformation. What it 
taught me is that importing a function doesn't mean using it, and that 
my code review was focused on "which functions exist?" 
when it should focus on "which functions get called?"

The mental model that helped me most was Trust Calibration. 
At the start of the review, my instinct was to review everything with 
the same intensity. But when I applied Trust Calibration 
— low trust in auth and security, high trust in 
boilerplate — I found the critical problems much 
faster. The first 30 minutes focused on config.py, 
auth_service.py, and routes/auth.py gave me 4 of the 
Critical findings. If I had started with main.py 
or models.py, I would have wasted time on low-severity 
problems.

It surprised me that the SQL injection in the task 
filters (services/task_service.py) was subtler than 
the one in the user search. The search uses an obvious 
f-string: f"...WHERE name LIKE '%{query}%'". But the 
filters in get_tasks() also use f-strings for status 
and priority, and I only noticed that on the second pass. 
It taught me that SQL injection isn't always an f-string 
in a WHERE — it can be anywhere in the query 
where user input gets inserted.

Claude Code was useful for verifying that the 
pydantic_settings import didn't exist in the installed version. 
I asked it "is BaseSettings in pydantic 2.9 or does it need 
pydantic-settings separately?" and it confirmed that it's a separate 
package. It also helped me understand the pagination 
offset — I gave it the formula and it confirmed that 
page * size skips the first page. In both cases, 
I verified its answer against the documentation.

What I'd do differently: I'd spend the first 5 minutes 
tracing the complete flow of each operation before 
hunting for bugs. I did the review file by file, and that 
made me lose the connection between layers. I would have 
found the plaintext password bug earlier if I 
had traced the register → hash → insert → DB flow 
from start to finish.

---

## Concrete actions for my workflow

1. Always trace the complete data flow before 
   reviewing individual files, especially for auth 
   and operations with sensitive data.
2. Apply Trust Calibration at the start of every code review: 
   mark the files as "high trust" or "low trust" 
   and start with the low-trust ones.
3. Look for SQL injection in EVERY place where queries are 
   built, not just the obvious ones. Create a grep for f-strings 
   near execute/cursor.

Example of an Excellent Justification

So you can calibrate the expected quality, here's a complete example of a justification for a fix:

## Fix #3: SQL Injection in User Search

**Finding:** #3 — The search_users() endpoint uses an f-string to 
build the SQL query
**Severity:** Critical
**File:** routes/users.py
**Affected lines:** 28-30

### What I changed
I replaced the f-string query:
  f"SELECT id, email, name FROM users WHERE name LIKE '%{query}%'"
with a parameterized query:
  "SELECT id, email, name FROM users WHERE name LIKE ?"
  with the parameter (f"%{query}%",)

I also added Depends(get_current_user) to the endpoint to 
require authentication.

### Why the original code was incorrect
The query built with an f-string is vulnerable to SQL injection 
(RF-06.2). An attacker can send as the query:

  test' UNION SELECT password, email, name FROM users--

This modifies the SQL query to extract the passwords of every 
user. On top of that, the endpoint doesn't require authentication 
(RF-02.4), letting anyone run the attack 
without even having an account.

### Why my correction is correct
1. SQL parameters (?) are escaped automatically by 
   SQLite, preventing the injection of arbitrary SQL
2. The LIKE pattern is built in Python (f"%{query}%") 
   and passed as a parameter, not concatenated into the query
3. I verified it by running the same SQL injection payload:
   the query now literally searches for the attack string 
   as a name, returning 0 results
4. Depends(get_current_user) ensures that only authenticated 
   users can search

### Regenerate/edit decision
- **Decision:** Edit
- **Justification:** There are two changes: parameterize the query 
  (2 lines) and add the auth dependency (1 line). The 
  rest of the function is fine. Regenerating would be disproportionate 
  for a 3-line change.

### Verification
- **Method:** I ran curl with a SQL injection payload
- **Result before the fix:** 
  It returned every user with their passwords
- **Result after the fix:** 
  It returned an empty list (literal search, no injection)
- **Additional method:** I tested without an auth token
- **Result:** 401 Unauthorized (correct)

Contrast: an insufficient justification

## Fix #3: SQL Injection

I changed the query to use parameters. 
I also added authentication.

The difference is obvious. The first justification shows that you understand the problem, the solution, and that you verified it works. The second only says what you did without explaining why.


How to Write a Good Retrospective

The structure that works

An effective retrospective has three parts:

  1. Observations: What happened during the project (facts, not opinions)
  2. Reflections: What you learned from what happened
  3. Actions: What you'll do differently in the future

Signs of a superficial retrospective

These phrases indicate a lack of reflection:

  • ❌ "I learned a lot with this project" — What exactly did you learn?
  • ❌ "It was very interesting" — Why? What interested you?
  • ❌ "The bugs were hard" — Which ones? Why were they hard for you?
  • ❌ "I used Claude Code and it helped me" — With what? How did you verify?
  • ❌ "Everything went well" — Was there nothing to improve?

Signs of a reflective retrospective

These phrases indicate genuine reflection:

  • ✅ "I didn't catch the SQL injection in the filters until the second pass because I was focused on the obvious f-strings"
  • ✅ "The Trust Calibration mental model made me start with auth_service.py, where I found 3 of the 4 Critical findings"
  • ✅ "Claude Code confirmed for me that pydantic_settings is a separate package, but I should have checked requirements.txt first"
  • ✅ "Next time, I'm going to trace the complete data flow before reviewing individual files"

Frequently Asked Questions

What if I didn't find every problem?

That's normal. The project has 15-20 problems and finding 12-14 is a solid result. What matters isn't perfection — it's the process and the reflection. If you found 10 of 18, reflect in the retrospective on why you missed 8 and what you'd do differently.

Can I go back to earlier phases?

Yes. The process isn't strictly linear. If during the correction you discover a new finding, add it to the findings document. If during the retrospective you realize you skipped something, mention it. The iterative process is more realistic than the linear one.

How long should the findings document be?

The findings table must have as many rows as the problems you found (ideally 12-18). The executive summary must be 2-3 sentences. The process notes are optional but recommended.

Do the justifications have to be long?

No. Each justification must be concise but complete: what changed (1-2 sentences), why it was incorrect (1-2 sentences with a reference to the requirement), why your fix is correct (1-2 sentences), regenerate/edit decision (1 sentence). Between 4 and 8 sentences per fix.

Can the retrospective be longer than 500 words?

Yes, but it doesn't need to be. A concise, reflective 350-word retrospective is better than an 800-word one that repeats the same points. Aim for depth, not length.


Complete List of Codebase Problems

After completing your delivery, you can compare your findings against this complete list. Don't read it before finishing your project.

See the complete list of problems (SPOILERS — only after delivering)

Critical problems (4)

  1. Hardcoded JWT Secret — config.py, line 12. JWT_SECRET_KEY has the fallback "super-secret-key-taskflow-2026". Category: Security.

  2. Plaintext Password — routes/auth.py, line 18-20. register() inserts user.password without hashing. The hash_password function is imported but never called. Category: Security.

  3. SQL Injection in Search — routes/users.py, line 28-30. search_users() uses an f-string: f"...WHERE name LIKE '%{query}%'". Category: Security.

  4. Endpoint with no Authentication — routes/users.py, line 25-30. search_users() doesn't have Depends(get_current_user). Category: Security.

High problems (4)

  1. Hard Delete instead of Soft Delete — services/task_service.py, line 98-101. delete_task() uses DELETE FROM instead of UPDATE ... SET status = 'deleted'. Violates RF-03.6. Category: Logic.

  2. Doesn't verify task ownership — services/task_service.py, line 23-28. get_task_by_id() doesn't filter by user_id. Any user can see any task. Violates RF-03.7. Category: Logic.

  3. Statistics include deleted tasks — services/task_service.py, line 107-120. get_user_stats() doesn't exclude tasks with status "deleted". Violates RF-04.2. Category: Logic.

  4. Insufficient password validation — models.py, line 14-16. Accepts 4+ characters, RF-01.4 requires 8+. Category: Logic.

Medium problems (6)

  1. SQL Injection in task filters — services/task_service.py, line 47-51. Uses f-strings to insert status and priority into the query. Violates RF-06.2. Category: Security.

  2. Division by zero in statistics — services/task_service.py, line 118. completion_percentage = by_status.get("completed", 0) / total * 100 crashes if total = 0. Category: Edge Case.

  3. Off-by-one pagination — services/task_service.py, line 55. offset = page * size. For page=1, offset=10, skipping the first page. It should be (page - 1) * size. Category: Edge Case.

  4. Insufficient title validation — models.py, line 37-40. Accepts titles of 1+ character. RF-05.1 requires 3-100. Category: Validation.

  5. No priority validation — models.py. There's no validator restricting priority to low/medium/high. It accepts any string. Violates RF-05.2. Category: Validation.

  6. Pagination accepts page=0 — routes/tasks.py, line 30. ge=0 should be ge=1. Violates RF-05.4. Category: Edge Case.

Low problems (5-6)

  1. Import of a nonexistent package — main.py, line 3. from pydantic_settings import BaseSettings. The package isn't installed. The class isn't used. Category: Hallucination.

  2. Import of a nonexistent function — services/auth_service.py, line 7. from bcrypt import verify_hash. The verify_hash function doesn't exist in bcrypt. The real functions are hashpw, gensalt, checkpw, kdf. Category: Hallucination.

  3. Invented parameter in fetchall() — services/task_service.py, line 62. cursor.fetchall(as_dict=True). sqlite3's fetchall() method doesn't accept parameters. Causes a TypeError when listing tasks. Category: Hallucination.

  4. No status validation — models.py. There's no validator to restrict status to pending/in_progress/completed. Violates RF-05.3. Category: Validation.

  5. Permissive CORS — main.py, line 16-21. allow_origins=["*"]. It isn't a functional bug but it's bad security practice. Category: Security (Low).

  6. DEBUG hardcoded to True — config.py, line 8. DEBUG: bool = True. In production it would expose stack traces. Violates RF-06.3. Category: Security (Low).


Detailed Self-assessment

After completing your delivery, use this guide to calculate your score:

Step 1: Count your findings

Compare your findings document against the complete list of problems (in the spoilers section above). For each finding:

  • ✅ Found and correct: You identified it and the description is accurate → counts as a finding
  • ⚠️ Found but incomplete: You identified it but the description is vague or the severity is incorrect → counts as 0.5
  • ❌ Not found: It doesn't appear in your findings document → doesn't count
  • ❌ False positive: You reported something that isn't a real problem → subtract 0.5

Step 2: Assess your corrections

For each fix you implemented:

  • ✅ Correct and verified fix: The fix solves the problem without introducing others → full credit
  • ⚠️ Partial fix: It solves part of the problem or the verification is incomplete → half credit
  • ❌ Incorrect fix: It introduces new problems or doesn't solve the original one → no credit

Step 3: Assess your process

Ask yourself these questions honestly:

  1. Did you follow the phases in order or jump between them?
  2. Did you document the debugging in real time or at the end?
  3. Did you prioritize by severity or by convenience?
  4. Did you verify each fix before moving on to the next?
  5. Did you use Claude Code strategically or indiscriminately?

Step 4: Assess your retrospective

Read your retrospective and ask yourself:

  • Does it have specific examples or only generalities?
  • Does it mention which mental models you used?
  • Does it identify concrete areas for improvement?
  • Are the actions implementable in your daily work?

What to Do After Delivering

If you scored 90+

Excellent. You have a solid professional process. The next steps:

  • Apply the checklist in your daily PRs
  • Teach the process to a teammate
  • Contribute additional items to the checklist based on your experience

If you scored 75-89

Good work. You have the foundations but there are areas to improve. Recommendations:

  • Review the findings you missed — why didn't you see them?
  • Practice with another codebase applying the same process
  • Reinforce the module that corresponds to your weakest category

If you scored 60-74

You completed the project but there are significant gaps. Recommendations:

  • Review modules 3, 4, and 5 with special attention to the exercises
  • Practice the code review checklist with simpler code first
  • Do the project a second time after reviewing the modules

If you scored less than 60

Don't get discouraged — this indicates that you need more practice with the individual modules before the capstone project:

  • Review and complete all the exercises from modules 3-6
  • Make sure you understand every item in the module 4 checklist
  • Repeat the project after completing the modules

Connection with the Next Guide

What you learned in this guide

With this project completed, you have a demonstrated professional process for handling AI-generated code:

  • ✅ Awareness: You know that AI code needs rigorous validation (Module 1)
  • ✅ Mental models: You have frameworks for deciding what to review and when (Module 2)
  • ✅ Detection: You can identify subtle hallucinations (Module 3)
  • ✅ Code review: You have a professional 20-item checklist (Module 4)
  • ✅ Patterns: You recognize the most common errors in AI code (Module 5)
  • ✅ Debugging: You can diagnose runtime bugs with Claude Code (Module 6)
  • ✅ Decisions: You know when to regenerate vs edit (Module 7)
  • ✅ Integration: You can apply it all together on a real codebase (Module 8)

What comes next

Guide 7: Git Workflows with Claude Code applies everything you learned here to the context of teams and version control:

  • Code review in PRs: The checklist you built here applies to real Pull Requests generated by Claude Code
  • Branching flows: How to structure branches when you use AI to generate code
  • Commits with AI: How Claude Code can generate commits, and how to validate that the messages and changes are correct
  • Collaboration: How to work as a team when some members use AI and others don't
  • Quality gates: Automating AI code checks in the CI/CD pipeline

The skill you demonstrated in this project — receiving code, evaluating it with judgment, correcting it, and documenting your process — is exactly what you'll do every day when you review PRs from teammates who use Claude Code. The difference is that now you have a professional process to do it.


Summary of the Skills You Demonstrated

By completing this project, you've demonstrated the following professional skills:

Technical skills

SkillWhere you demonstrated it
Detecting hallucinations in imports and APIsFindings for pydantic_settings, verify_hash, fetchall(as_dict)
Identifying SQL injectionFindings in routes/users.py and services/task_service.py
Verifying password handlingFinding of the plaintext password in routes/auth.py
Assessing security configurationFinding of the hardcoded JWT secret
Detecting incorrect business logicFindings for delete, authorization, statistics
Finding edge casesFindings for pagination, division by zero
Systematic debuggingReproducing and confirming runtime bugs
Justified code correctionFixes with explanation and verification

Process skills

SkillWhere you demonstrated it
Prioritization by severityOrder of corrections (Critical → Low)
Professional documentationFindings document with the complete format
Strategic use of AI toolsSpecific questions to Claude Code with verification
Informed decisionsRegenerate vs edit framework applied
Reflection and continuous improvementRetrospective with concrete actions

Communication skills

SkillWhere you demonstrated it
Reporting findings with contextFindings table with severity and impact
Justifying technical decisionsJustifications document
Communicating riskCorrect severity classification
Written reflectionArticulated retrospective

These aren't theoretical skills — you've just exercised them with real code, real problems, and real documentation. The next time you receive a PR to review, these skills will be there.


Final Checklist Before Delivering

Use this list to verify that your delivery is complete:

Findings Document

  • It has reviewer information (name, date, time)
  • It has an executive summary (2-3 sentences)
  • Findings table with all the columns: #, severity, category, file, lines, description, requirement, impact
  • It has at least 12 documented findings
  • Every Critical finding has the correct severity
  • It has a findings statistics table
  • It has process notes

Corrected Code

  • Every corrected file has a corrections comment at the top
  • Every Critical severity fix is implemented
  • Every High severity fix is implemented
  • Most Medium fixes are implemented
  • The corrected codebase runs with no errors
  • The basic endpoints work correctly

Justifications

  • Every fix has a written justification
  • Every justification includes: what changed, why it was incorrect, why the fix is correct
  • Every justification references the functional requirement violated
  • Every justification documents the regenerate/edit decision
  • The justifications include how each fix was verified

Retrospective

  • It's between 300-500 words
  • It includes specific examples (not just generalities)
  • It mentions which mental models or techniques were most useful
  • It identifies what was hard and why
  • It includes at least 3 concrete actions for the daily workflow
  • It's honest and reflective

Closing

This project isn't the end of your learning — it's the beginning of a habit. The first time you do a code review of AI-generated code with the module 4 checklist, it's going to be slow. The fifth time, it'll be faster. The twentieth time, it'll be automatic. And the hundredth time, you'll find a bug that would have reached production if you hadn't reviewed.

That's the value of this project: not the code you fixed today, but the process you internalized to fix all the code you're going to receive tomorrow.

What separates developers who use AI from developers who master AI isn't the tool — it's judgment. And judgment is built by practicing exactly what you did here.


Debugging & Code Review with Claude Code — Module 8, Capsule 05 Claude Code Agentic Development Path — Guide #6 of 11