Session M2-04 lab: Code review workflows¶
Duration: 2 hours
Difficulty: Intermediate
Prerequisites: Sessions M1-01 to M1-03, M2-01 to M2-03 completed
Deliverable: A human-reviewed change record, corrected starter project, and conflict review
Lab overview¶
You will review AI-assisted work within the named files. Support your comments with code references and test results, then apply targeted fixes and decide whether to accept the change. The starter contains deliberate defects so you can compare your own review with Copilot-assisted review.
| Exercise | Topic | Time |
|---|---|---|
| 1 | Human, code, and security review of one diff | 40 min |
| 2 | Validate and correct the starter project | 35 min |
| 3 | Resolve a conflict and check the result | 25 min |
| 4 | Review the results and make a final decision | 20 min |
Access and cost preflight¶
Read the course safety baseline. Before the lab, check the repository, synthetic data, reviewer, test command, and any usage limit.
Before you start, record these decisions in your notes:
- Repository scope: Are you using only
lab/starter/review-project/, a private training fork, or an approved internal sandbox? - Data boundary: Are all examples synthetic and allowed for review tooling?
- Review surface: Is Copilot review available?
- Required checks: Which command proves the starter project still works?
- Stop condition: What requires you to stop automated work?
You need the standalone Copilot CLI with /review and /security-review,
Copilot pull-request review, a private training repository you may push to, Git,
the authenticated GitHub CLI (gh), Node.js, and npm. Check both Copilot commands
in /help and repository access with gh auth status before starting.
If a required command or review access is unavailable, stop the lab. A generic
chat review or worksheet does not replace the local commands and pull-request
practice. /security-review examines current changes; it does not replace
repository security scanning.
Setup¶
Use these starter assets:
lab/starter/review-project/package.json: project scripts and dependencieslab/starter/review-project/src/api.js: Express API under reviewlab/starter/review-project/src/utils.js: utility functions under reviewlab/starter/review-project/tests/api.test.js: existing Jest/Supertest checkslab/starter/code-changes.md: intentionally flawed changes to reviewlab/starter/partner-review-checklist.md: structured review worksheetlab/starter/fix-evaluation-template.md: finding, fix, and test recordlab/starter/conflict-scenario/README.md: manual merge-conflict scenariolab/starter/conflict-scenario/utils-with-conflict.js: conflict exercise source file
Create a workspace outside the curriculum folder. This keeps the source materials unchanged:
mkdir -p ~/copilot-labs/session-m2-04
cp -R lab/starter/review-project ~/copilot-labs/session-m2-04/review-project
cd ~/copilot-labs/session-m2-04/review-project
npm install
npm test
git init
printf 'node_modules/\n' > .gitignore
git add .gitignore package.json package-lock.json src tests
git commit -m "Record review baseline"
git branch -M main
git switch -c feature/add-user-management
Expected:
npm installcompletes without new dependencies andnpm testreports that the existing API tests pass.If install or tests fail: Stop and fix the environment. Static review alone does not complete the lab. Do not change package versions to hide a failure.
Use a fresh folder for this local repository. Ask the trainer for an empty
private training repository. Before applying the change brief, add its URL as
origin and push the baseline:
The baseline must be the same commit locally and remotely so the PR contains only the intended change. If the remote already has commits, stop and ask for an empty training repository. Do not force-push or push intentional defects to a public repository.
Exercise 1: Review one diff through three passes (40 minutes)¶
Objective¶
Review a deliberately flawed change set. Support each risk with a code reference or test result and name the acceptance criterion it affects.
Steps¶
- Open the change brief. Read
lab/starter/code-changes.mdfrom start to finish.
Check: The brief lists changes to
src/api.jsandsrc/utils.js. Each has an intended defect.
- Open
lab/starter/fix-evaluation-template.md. Use its single triage table for human, local-command, and PR findings throughout the lab.
Success criteria: Each finding names a file or function, the affected acceptance criterion, and the code or test output that supports it.
- Inspect the current starter project before applying changes. Open
src/api.js,src/utils.js, andtests/api.test.js.
Check: The baseline has a small API, utility functions, and existing tests. Record its behavior so you can separate existing code from introduced defects.
- Apply the change brief on
feature/add-user-management. Keep these changes uncommitted until both local reviews have finished. Checkgit diff -- src/api.js src/utils.jsagainst the brief.
Success criteria: The modified files match the change brief closely enough for review; you have not added unrelated features.
- Run the existing checks.
Expected output: Some existing tests may still pass because the defects are not fully covered. Record both pass/fail output and any missing coverage you notice.
- Review the change yourself first. Use
lab/starter/partner-review-checklist.mdto record your initial verdict. Record the two findings that matter most in the triage table withHumanas their source before opening an assisted review.
Success criteria: Your initial review cites the relevant file or function and explains how the code or test output supports your verdict.
- Run the general code review. Start
copilotin the working repository:
/review Review the current changes to src/api.js and src/utils.js for
correctness and missing tests. Cite file and line references. Review only;
do not edit files.
- Run the focused security review on the same diff:
Keep src/api.js and src/utils.js as the only modified project files during
these runs. The command reviews staged and unstaged changes; committing the
patch first would remove it from that scope.
- Triage both outputs in
fix-evaluation-template.md. Keep your original human review unchanged. For each finding, name the source, file/line, claimed impact, and reproduction or code reference. Accept, reject, or leave unresolved with a reason. If a review reports no findings, record that.
The search route builds SQL text but connects to no database. Reject a claim that this lab proves database compromise. Synthetic key-shaped strings also do not prove a leaked real credential. Keep actual data exposure separate from unsafe patterns and maintainability suggestions.
-
Open the training PR after the local reviews. Commit only the intended files, push to the trainer-provided private remote, and open a PR:
git add src/api.js src/utils.js git commit -m "Add synthetic user-management change for review" git push -u origin feature/add-user-management gh pr create --base main --title "Review synthetic user management" \ --body "Training-only change. Contains intentional defects; do not merge."The remote must already contain the baseline
mainbranch. Request Copilot review from the PR page and record at least one comparison with the local results. Do not merge the intentionally flawed change.
Checkpoint¶
You are ready to continue when you can answer:
- Which findings block approval?
- Which findings are suggestions only?
- Which defects were not covered by the existing tests?
- Which code checks or test results would show that the fixes are complete?
- What changed after the assisted review, if anything?
- What did
/reviewand/security-revieweach report? - Which claim was supported by actual behavior rather than an assumed backend?
Exercise 2: Validate and correct the starter project (35 minutes)¶
Objective¶
Fix the defects with the smallest safe changes. Then show that the corrected project meets the review criteria.
Steps¶
- Prioritize blocking findings. Start with issues that can leak sensitive data, allow injection, crash the server, or produce incorrect behavior.
Success criteria: Your fix plan lists each blocking defect, the target file, and the check you will run.
- Fix input handling in
src/api.js. Replace unsafe string interpolation and fragile parsing with validated inputs and safe response shapes that fit the starter project.
Expected: The endpoint handles empty, missing, malformed, and valid inputs predictably. Tests or manual requests show the error responses.
- Fix sensitive response data. Remove password-like or token-like fields from user-facing responses.
Success criteria: Inspecting the JSON response shows only fields needed by the API contract.
- Fix pagination in
src/utils.js. Check that page 1 begins with the first item and boundary cases return predictable results.
Expected output: A focused test or manual Node.js check demonstrates page 1, page 2, and empty collections.
- Add or update focused tests in
tests/api.test.js. Cover the behavior that was missing from the original test suite.
Success criteria: New tests fail before the fix and pass after the fix.
- Run checks again.
Expected output: All tests pass. If tests fail, record the failing assertion and correct only the related implementation or test expectation.
-
Update the existing triage rows in
lab/starter/fix-evaluation-template.md. Add the fix and regression test to each accepted finding. Record residual risk in its Human decision section. -
Before committing the fixes, rerun
/reviewand/security-reviewon the correction diff. Compare the results with the initial findings. Rerunnpm test, then commit and push only the reviewed fixes to the same training PR. A clean automated review does not approve the PR.
Checkpoint 2: fixes trace to findings¶
- Every blocking finding maps to a focused fix.
- New tests cover the missed behavior.
-
npm testpasses. - The fix evaluation names residual risk.
Exercise 3: Resolve a conflict (25 minutes)¶
Objective¶
Resolve a merge conflict so both branches' intended behavior survives. Check the result rather than accepting one side without review.
Steps¶
- Read the scenario. Open
lab/starter/conflict-scenario/README.md.
You should observe: Two branches modify
src/utils.js; one adds date formatting and the other changes price formatting.
- Open the conflicting source. Review
lab/starter/conflict-scenario/utils-with-conflict.js.
Expected output: You can identify the conflicting region and state what each side is trying to accomplish.
- Write the desired merged behavior before editing. Use a short decision statement:
Preserve formatDate for date display and preserve formatPrice with an explicit
currency parameter. Existing callers should continue to work or be updated
intentionally.
Success criteria: Your statement names both branch intentions and the behavior that tests must prove.
- Resolve the conflict manually. Remove conflict markers, keep both valid behaviors, and avoid unrelated formatting changes.
Expected output: The file contains no
<<<<<<<,=======, or>>>>>>>markers.
- Add focused tests. Check date formatting, default currency behavior, the supplied currency behavior, and any unchanged helper behavior.
Success criteria: Tests show that neither branch's intended behavior was lost.
- Run the project test command.
Expected output: The tests pass. Save the output for review.
- Peer review the resolution. Ask a partner to review only the conflict resolution and tests.
Success criteria: The reviewer can explain why both original branch goals are represented in the merged result.
Checkpoint 3: conflict intent is preserved¶
- No conflict markers remain.
- Both branch goals appear in the resolved behavior.
- Tests cover date and currency formatting.
- A peer can explain the merge decision from the record.
Exercise 4: Review the code and test results (20 minutes)¶
Objective¶
Use the code and test results to make your final review decision. An automated suggestion alone is not enough.
Steps¶
- Select one blocking finding from Exercise 1. Choose a security, correctness, or reliability issue.
Success criteria: The finding includes a file reference, impact, and acceptance criterion.
- Check the selected finding's triage row. Add any missing before/after behavior, test names, or command output; do not create a second record.
Expected output: A reviewer can reproduce the result from your notes and command output.
- Classify remaining risk. Use these categories:
| Risk type | Question |
|---|---|
| Data | Did the change expose or process restricted data? |
| Dependency | Did the change add or update packages? |
| Permission | Did the workflow require a new permission? |
| Security | Did validation, error handling, or secrets handling change? |
| Quality | Do the tests and review results support the decision? |
- Complete Human decision in
fix-evaluation-template.md. Choose approve, request changes, or pause. Name the human reviewer and explain the decision.
Success criteria: The decision is understandable without seeing the entire lab conversation.
- Compare the initial human review with both local command outputs and the PR review. Complete the remaining fields in the same template. Preserve the original critique, record which source raised each finding, and explain why the human reviewer accepted, revised, or rejected it.
Expected output: The triage table identifies differences, false positives, new code references or test results, and any finding that changed the final verdict.
Checkpoint 4: final decision cites findings and checks¶
- The decision is approve, request changes, or pause.
- The rationale cites findings, fixes, and check results.
- Automated findings were accepted only after human review.
- Remaining risk and the reviewer are named.
Final deliverable¶
Submit one folder or document containing:
partner-review-checklist.mdwith the unchanged initial human verdict.fix-evaluation-template.mdwith the review runs, finding triage, fixes, test results, remaining risk, reviewer, and final human decision.- Initial and correction outputs from
/reviewand/security-review, the private training PR reference, and test output for the corrected project. - The resolved conflict decision and its test results.
Done: A reviewer can reconstruct the original risk, fix, checks, and final decision from your notes and command output.
Verification checklist¶
- Findings cite code or test results and acceptance criteria.
- A human reviewer made the final decision.
- Both local commands ran before the initial change was committed.
- Findings name their review source and a file/line or reproduction.
- Unsupported exploit claims are rejected or left unresolved with a reason; no-findings results are recorded.
- Both commands ran again on the correction diff before it was committed.
- The private training PR received Copilot review; it was not merged.
- Required checks were run.
- Metered work stayed within the usage limit.
- Starter files used:
code-changes.md,partner-review-checklist.md,fix-evaluation-template.md,review-project/, andconflict-scenario/.