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.
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.
\, 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"
}
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?
To prove which change set the review evidence covered and to reason about freshness after the PR changed.
Why is a simulated CHANGES_REQUESTED fixture acceptable only when labeled?
It teaches diagnosis without fabricating a live independent review event; source truth and simulation must remain distinguishable.
What must happen before resolving the blocking conversation?
The underlying concern should be addressed by code, evidence, or an explicit accepted decision.
If checks pass after HEAD2 but no fresh required approval exists, is the review gate satisfied?
Not necessarily. Automated checks and human review requirements are separate gates.
Why own the CODEOWNERS file itself?
It reduces the risk that ownership routing can be weakened by an unreviewed policy-file change.
What is the Chapter 09 handoff condition?
The PR has understandable current review/check evidence; merge method and integration behavior can now be chosen deliberately.
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.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this
address.