Chapter 08Lesson 05~195 minutes

Checkpoint Lab — Code Review, Suggested Changes, CODEOWNERS, Review Requests, and Review Discipline

Run an integrated code-review checkpoint that touches two ownership domains, records a requested change and suggestion, updates the PR, evaluates review freshness and policy state, resolves conversations, and produces a production-ready review checklist.

CheckpointOwned pathsReview updateChecklist

Learning objectives

  • Build a disposable repository whose CODEOWNERS policy covers two review domains and owns the policy file itself.
  • Open a PR touching both domains and predict which owners/review routes should apply before inspecting GitHub.
  • Record one requested change and one suggested patch using an optional independent reviewer or a safe one-account simulation.
  • Update the PR and compare before/after head OIDs, submitted review commit IDs, review requests, checks, and conversation state.
  • Evaluate review freshness under an explicit policy and resolve discussions only after evidence-backed correction.
  • Produce a reusable review checklist separating correctness, security, operability, and style, then clean up without merging.
Availability: Mandatory checkpoint: GitHub.com, GitHub Free, one disposable public personal repository, Git, and GitHub CLI. A second free collaborator identity is optional for live independent Request changes/Approve behavior; otherwise use the supplied review-state fixture and submit non-blocking Comment feedback from the author account. Team CODEOWNERS and organization policy are optional.
Shell portability: multi-line examples with trailing \, command substitution such as $(...), here-documents, and printf are labeled Git Bash/Bash/zsh. In PowerShell, place the same Git/gh arguments on one line or use the backtick for continuation; PowerShell-native file-writing alternatives are shown where the shell syntax materially differs. GitHub review semantics do not depend on the shell.

1. Checkpoint mission and evidence package

Create c08-review-checkpoint with two owned areas: docs/ and services/payments/. Open one PR touching both. Capture the base/head OIDs, CODEOWNERS parser result, changed paths, expected owner matches, review requests, reviews and their commit IDs, suggestion/correction commit, check state, conversation disposition, and a written review operating policy. Do not merge.

2. Preflight and collision gate

gh auth status --active --hostname github.com
OWNER=$(gh api user --jq .login)
REPO="c08-review-checkpoint"

gh repo view "$OWNER/$REPO" >/dev/null 2>&1 && {
  echo "STOP: repository already exists" >&2
  exit 2
}

3. Establish two ownership domains

gh repo create "$OWNER/$REPO" --public --add-readme --clone
cd "$REPO"
mkdir -p .github docs services/payments

cat > .github/CODEOWNERS <<EOF
*                         @$OWNER
/docs/                    @$OWNER
/services/payments/       @$OWNER
/.github/CODEOWNERS       @$OWNER
EOF

cat > docs/retry.md <<'EOF'
# Retry policy
Retries must be bounded, observable, and reversible.
EOF

cat > services/payments/retry.conf <<'EOF'
max_retry_seconds=60
EOF

git add .github/CODEOWNERS docs/retry.md services/payments/retry.conf
git commit -m "chore: define review ownership domains"
git push
DEFAULT_BRANCH=$(git branch --show-current)
BASE_OID=$(git rev-parse HEAD)

gh api   -H "Accept: application/vnd.github+json"   -H "X-GitHub-Api-Version: 2026-03-10"   "repos/$OWNER/$REPO/codeowners/errors"   --jq '.errors'

Expected parser result is []. Stop if it is not empty. This prevents the checkpoint from “testing” a policy that GitHub did not actually load cleanly.

4. Create one PR that touches both owned paths

git switch -c review/c08-bounded-retry

cat >> docs/retry.md <<'EOF'

Reviewers should verify the configured retry ceiling against this policy.
EOF

cat > services/payments/retry.conf <<'EOF'
max_retry_seconds=120
EOF

git add docs/retry.md services/payments/retry.conf
git commit -m "docs: propose retry review policy"
git push -u origin review/c08-bounded-retry
HEAD1=$(git rev-parse HEAD)

PR_URL=$(gh pr create   --base "$DEFAULT_BRANCH"   --head review/c08-bounded-retry   --title "docs: checkpoint code review discipline"   --body "Touches docs and payments ownership domains; do not merge during the checkpoint.")
PR_NUMBER=${PR_URL##*/}

5. Prediction 1: ownership routing follows base-branch path matches

Before inspection, write: both changed files match explicit CODEOWNERS paths. GitHub will evaluate the CODEOWNERS file from the PR base branch. The PR head OID will remain HEAD1 merely because review metadata appears. Because the only owner is also the author, this one-account version does not produce independent owner approval.

gh pr view "$PR_NUMBER" --json   number,baseRefName,headRefName,headRefOid,files,reviewRequests,reviewDecision,latestReviews,statusCheckRollup,url

gh api   -H "Accept: application/vnd.github+json"   -H "X-GitHub-Api-Version: 2026-03-10"   "repos/$OWNER/$REPO/pulls/$PR_NUMBER/requested_reviewers"   --jq '{users:[.users[].login],teams:[.teams[].slug]}'

6. Record one requested change and one suggestion

Preferred live path: use a second disposable collaborator identity that has repository access. That reviewer opens Files changed, submits a Request changes review explaining that 120 exceeds policy, and adds this suggestion:

[blocking] The configured ceiling exceeds the documented operational bound.

```suggestion
max_retry_seconds=30
```

One-account fallback: add the same inline suggestion and submit the review as Comment. Then record the following realistic fixture in your notes to practice diagnosis without pretending the author supplied independent review:

{
  "reviewer": "reviewer-example",
  "state": "CHANGES_REQUESTED",
  "reviewed_head": "HEAD1",
  "blocking_reason": "retry ceiling exceeds documented bound"
}
Truthfulness rule: label the fixture as simulated. Do not present it as API evidence from the live PR.

7. Preserve review evidence before changing code

gh pr view "$PR_NUMBER" --json headRefOid,reviewRequests,latestReviews,reviewDecision,statusCheckRollup

gh api   -H "Accept: application/vnd.github+json"   -H "X-GitHub-Api-Version: 2026-03-10"   "repos/$OWNER/$REPO/pulls/$PR_NUMBER/reviews"   --jq '.[] | {id,reviewer:.user.login,state,commit_id,submitted_at}'

Save the output. If the second reviewer path was used, you should see their submitted review associated with HEAD1. In the fallback path, the live API shows only actual review/comment data; the synthetic change-request fixture remains separate.

8. Prediction 2: correcting the suggestion moves the PR head and can change review freshness

Write: applying or reproducing the suggested correction creates a new commit and therefore a new head OID HEAD2. Existing review evidence still records what was submitted against HEAD1. Whether approval/change-request state is automatically dismissed or remains active depends on configured policy; the team must re-evaluate freshness.

9. Correct the change and verify the new commit range

printf 'max_retry_seconds=30
' > services/payments/retry.conf
cat >> docs/retry.md <<'EOF'
Validation evidence: retry ceiling now matches the operating policy.
EOF

git add services/payments/retry.conf docs/retry.md
git commit -m "fix: align retry ceiling with review policy"
git push
HEAD2=$(git rev-parse HEAD)

git fetch origin "$DEFAULT_BRANCH" review/c08-bounded-retry
git log --oneline "origin/$DEFAULT_BRANCH..origin/review/c08-bounded-retry"
git diff --stat "origin/$DEFAULT_BRANCH...origin/review/c08-bounded-retry"

gh pr view "$PR_NUMBER" --json headRefOid,commits,files,latestReviews,reviewDecision,reviewRequests
printf 'reviewed_before=%s
current_head=%s
' "$HEAD1" "$HEAD2"

10. Evaluate freshness under an explicit policy

Choose one policy for the checkpoint and document it. If using no live branch rule, this is a policy simulation, not an enforcement claim.

Checkpoint policy option Expected decision after HEAD2
Dismiss stale approvals Any relevant approval of HEAD1 must be re-approved for the new diff
Require approval of most recent reviewable push At least one authorized reviewer other than the latest pusher must approve after HEAD2
Manual freshness only Reviewer/author explicitly re-request review and record why old approval is or is not still sufficient

If you used the optional second reviewer, re-request their review after the fix. That reviewer should inspect the new diff and, if satisfied, submit Approve. Do not have the author claim that this independent event occurred in the fallback path.

11. Resolve discussions after the correction is inspectable

Reply to the blocking thread with the correction commit/OID and validation explanation, then resolve the conversation. If your repository rule requires conversation resolution, this removes that specific gate. It does not replace a required approval or failed check.

12. Produce the production review checklist

Dimension Reviewer asks Evidence/examples
Correctness Does behavior satisfy the intended contract and edge cases? Diff, tests, invariants, error paths
Security Does the change alter trust, permissions, secrets, validation, dependencies, or attack surface? Threat reasoning, security checks, least privilege
Operability Can operators observe, roll back, and troubleshoot the change? Logs/metrics, timeout/retry bounds, runbook, rollback
Style / maintainability Is the code understandable and consistent without blocking on cosmetic preference? Naming, structure, automated formatting/linting
Scope Is unrelated work excluded or explicitly split? Commit list and three-dot diff
Freshness Did the final reviewer inspect the current head/diff? Current head OID, review commit IDs, configured policy
Automation What do checks prove, and what remains human judgment? StatusCheckRollup and review notes

13. Final verification checklist

  • CODEOWNERS parses without errors and is on the PR base branch in a supported location.
  • Both changed paths match the intended ownership rules.
  • PR head OID changed from HEAD1 to HEAD2 only when the corrective commit was added.
  • Actual review records are distinguishable from any fallback simulation fixture.
  • Review commit IDs and current head OID are recorded for freshness reasoning.
  • Blocking concern is addressed by code/evidence before conversation resolution.
  • Checks, review state, merge state, and deployment state are not conflated.
  • No secrets, production data, force pushes, policy bypasses, or repository transfers were used.

14. Cleanup and rollback

Close the PR without merging, archive the disposable repository after an owner/name identity check, and remove the local clone. If a collaborator was added only for this lab, remove their access first if desired. Permanent deletion is optional and not part of the mandatory checkpoint.

gh pr close "$PR_NUMBER" --comment "Chapter 08 checkpoint complete; intentionally not merged."
cd ..
printf 'archive-check=%s/%s
' "$OWNER" "$REPO"
gh repo archive "$OWNER/$REPO"
rm -rf "$REPO"

15. What Chapter 08 adds to the production GitHub operating model

The operating model now has explicit human change assurance: ownership is encoded near the code, reviewer routing is observable, feedback severity is meaningful, suggested changes remain proposals until committed, approval freshness is policy-driven, and human review is kept separate from automated evidence. This is the foundation for making merge rules enforceable without reducing review to ceremony.

16. Bridge to Chapter 09: merge methods and integration policy

Chapter 08 ends with a PR whose review evidence is understandable. Chapter 09 asks what happens next: merge commit, squash, or rebase; auto-merge; merge queue; conflicts; cleanup; and how integration choices change history while respecting the review evidence you established here.

Knowledge check

Why did the checkpoint record HEAD1 before review and HEAD2 after correction?

Why is a simulated CHANGES_REQUESTED fixture acceptable only when labeled?

What must happen before resolving the blocking conversation?

If checks pass after HEAD2 but no fresh required approval exists, is the review gate satisfied?

Why own the CODEOWNERS file itself?

What is the Chapter 09 handoff condition?

Next chapter

Merge Methods, Auto-Merge, Merge Queue, Conflict Handling, and Branch Cleanup: Concepts, Architecture, and Mental Model

Authoritative references

 About code owners
 Incorporating feedback in your pull request
 About pull request reviews
 Requesting a pull request review
 About protected branches
 Available rules for rulesets
 gh pr review
 gh pr view
 gh pr checks
 REST API endpoints for pull request reviews
 REST endpoint: list CODEOWNERS errors
 REST API versions

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.