Code Review, Suggested Changes, CODEOWNERS, Review Requests, and Review Discipline: Concepts, Architecture, and Mental Model
Build a review mental model in which comments, approvals, change requests, conversations, CODEOWNERS, review requests, checks, and branch policy are distinct GitHub signals around a changing pull-request head commit.
Learning objectives
- Distinguish a general comment, pending review, submitted Comment review, Approve review, and Request changes review as different GitHub review states.
- Explain review conversations and resolution without treating “resolved” as proof that the underlying code is correct.
- Explain review requests, team reviews, CODEOWNERS matching, and required code-owner approval as separate routing and enforcement mechanisms.
- Treat suggested changes as reviewer-authored patch proposals that create commits only when someone with the required access applies them.
- Reason about review freshness when the pull-request head or merge base changes and distinguish stale-review dismissal from last-push approval policy.
- Separate human review evidence from automated checks and security scanning, and inspect review state read-only before changing anything.
1. The practical problem: “approved” is not a review operating model
Chapter 07 gave you a pull request as a change-control object. The next failure mode is organizational: teams add an approval button to the process but never define what approval means, who owns which paths, which feedback blocks merge, or what happens when new commits arrive. GitHub exposes several review signals; reliability comes from assigning each signal a precise meaning.
2. Comment, Approve, Request changes, and pending review
When reviewing Files changed, you may create line comments and keep them in a pending review. Those comments are not yet submitted to the author as a finished review. On submission, GitHub gives the review one of three dispositions: Comment records feedback without approval semantics; Approve states that the reviewer accepts the proposed changes; Request changes records that the reviewer believes changes are required before integration. Repository policy determines whether approval or a change request becomes a merge gate.
| Signal | What it means | What it does not prove |
|---|---|---|
| Pending review | Reviewer is accumulating comments before submission | No final disposition has been communicated |
| Comment | Feedback submitted without approval/change-request state | Not an approval |
| Approve | Reviewer accepts the reviewed proposal | Not deployment success; not permanent freshness |
| Request changes | Reviewer says correction is required | Blocking effect depends on repository review policy and permissions |
3. Review conversations and resolution are workflow state
An inline review comment starts a discussion thread tied to a file/line context. Replies create a conversation. Marking that conversation resolved is bookkeeping: it says the team considers the thread addressed or acknowledged. A ruleset or branch-protection rule can require all conversations to be resolved before merge, but resolution itself does not execute tests, prove correctness, or remove the historical discussion.
4. Review requests, teams, and CODEOWNERS are different layers
flowchart TD PR["PR head OID"] --> DIFF["Changed paths"] BASE["CODEOWNERS on base branch"] --> MATCH["Path matching"] DIFF --> MATCH MATCH --> RR["Automatic review request"] MAN["Manual request"] --> RR RR --> HUMAN["Human reviewer"] HUMAN --> REV["Review state"] POLICY["Branch protection / ruleset"] --> GATE["Merge gate"] REV --> GATE CHECKS["Automated checks"] --> GATE
A review request is routing: GitHub asks a user or team to look at the PR. A CODEOWNERS file is repository content that maps path patterns to users or visible organization teams. When a ready PR changes owned paths, GitHub can request those owners automatically. A required code-owner review is enforcement configured by branch protection or a ruleset. Routing and enforcement are related but not identical.
For CODEOWNERS to route correctly, GitHub reads the file from the
base branch of the PR. Supported locations are
.github/CODEOWNERS, CODEOWNERS at
repository root, or docs/CODEOWNERS, searched in that
order. Owners must have write access; organization teams must be
visible and have write access.
5. CODEOWNERS matching is policy code: order, case, and unsupported syntax matter
CODEOWNERS resembles .gitignore, but it is not
identical. The
last matching pattern takes precedence. Paths are
case-sensitive. Negation with ! and character ranges
such as [a-z] are not supported. Invalid lines are
skipped, and GitHub exposes CODEOWNERS syntax errors through the UI
and REST API. This makes the file testable policy rather than magic
text.
# Default ownership first
* @octo-owner
# Later matches take precedence
/docs/ @octo-docs
/services/payments/ @octo-payments
/.github/CODEOWNERS @octo-owner
6. Suggested changes are proposals that can become commits
A reviewer can attach a suggested change to an inline comment. The suggestion is not automatically correct and does not modify Git until it is applied. A person with write access can apply a suggestion directly; multiple suggestions can be batched into one commit. GitHub records the suggesters as co-authors and the person applying the suggestion as a co-author/committer. Because applying a suggestion moves the PR head, it can affect review freshness and checks.
The retry interval should remain bounded.
```suggestion
const MAX_RETRY_SECONDS = 30;
```
7. Review freshness: new commits can change what an approval means
An approval refers to what the reviewer actually saw. GitHub offers two important policy strategies. Dismiss stale pull request approvals when new commits are pushed invalidates approvals when relevant new commits or merge-base changes affect the reviewed diff. Require approval of the most recent reviewable push preserves earlier approvals but requires at least one authorized reviewer other than the latest pusher to approve the newest push. These are not synonyms; they encode different risk/throughput tradeoffs.
| Policy | Security posture | Operational cost |
|---|---|---|
| Dismiss stale approvals | Strong freshness: changed reviewed content must be re-approved | More reviewer churn on frequently updated PRs |
| Approve most recent reviewable push | Ensures latest push gets independent approval without discarding every earlier approval | Requires careful interpretation of which approval covers which change |
| No freshness rule | Fastest flow | Team process must manually notice material post-approval changes |
8. Human review and automated checks answer different questions
Human reviewers reason about intent, architecture, maintainability, threat boundaries, failure behavior, and whether the change belongs in the system. Automated checks execute repeatable validations such as tests, linting, policy checks, or security analysis. Neither replaces the other. A green CI suite cannot prove the design is correct; a senior reviewer cannot prove every test matrix passed. Later security chapters deepen scanning evidence, but this chapter teaches the interface: treat each result as one evidence source.
9. Read-only inspection before changing review state
\, 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.
# Structured PR state: no review mutation.
gh pr view 42 -R OWNER/REPO --json number,title,isDraft,headRefOid,reviewDecision,reviewRequests,latestReviews,statusCheckRollup,url
# Current submitted reviews through versioned REST.
gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2026-03-10" "repos/OWNER/REPO/pulls/42/reviews" --jq '.[] | {id,user:.user.login,state,commit_id,submitted_at}'
# Requested reviewers are a separate API object.
gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2026-03-10" "repos/OWNER/REPO/pulls/42/requested_reviewers" --jq '{users:[.users[].login],teams:[.teams[].slug]}'
# CODEOWNERS parser evidence for the base/default branch.
gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2026-03-10" "repos/OWNER/REPO/codeowners/errors" --jq '.errors'
The review REST response includes the
commit_id associated with a submitted review. That
field is useful evidence when asking whether a later head OID has
moved beyond what a reviewer saw.
10. DevOps connection: review quality is a reliability and security control
A production review system must route expertise to relevant changes, preserve an auditable decision trail, and prevent unreviewed material from silently inheriting old approval. CODEOWNERS can make ownership visible; rules can enforce selected approval semantics; checks can supply repeatable evidence. The system still depends on reviewers asking concrete questions and authors responding with code or evidence rather than ceremony.
11. Lesson summary
GitHub review has several independent pieces: comments and pending reviews, submitted dispositions, review requests, CODEOWNERS routing, optional required-owner enforcement, conversation resolution, suggestions that can create commits, and freshness policies. The useful mental model is “evidence attached to a moving PR head under explicit policy,” not “green approval badge.”
Knowledge check
Does a review request mean the requested person has approved the PR?
No. A review request is routing/assignment. Approval is a submitted review state.
Where must CODEOWNERS exist to affect a pull request?
GitHub evaluates CODEOWNERS from the PR base branch, using .github/, repository root, or docs/ in that search order.
Why is applying a suggested change security/review relevant?
Applying it creates a commit on the PR compare branch, moving the head OID and potentially changing checks and review freshness.
What is the difference between stale-approval dismissal and “approval of the most recent reviewable push”?
The first dismisses approvals when relevant new changes arrive; the second keeps earlier approvals but requires independent approval covering the latest push.
A conversation is resolved. Does that prove the code is correct?
No. Resolution is review-thread workflow state; correctness still depends on code, tests, evidence, and reviewer judgment.
Authoritative references
About pull request reviews
About code owners
Incorporating feedback in your pull request
Requesting a pull request review
About protected branches
Available rules for rulesets
gh pr view
REST API endpoints for pull request reviews
REST API endpoints for review requests
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.