---
title: 'Contribution Guidelines'
source: 'https://academia.sh/en/courses/code-review/contribution-guidelines'
course: 'Code Review and Team Process'
language: en
updated: '2026-08-17T18:10:46+00:00'
license: 'CC BY-SA 4.0'
---

# Contribution Guidelines

A written expectation works before review: in a narrow review, as the guide's scope grows, rounds drop from 6 to 5, 4, 3, and 2; in a wide review, rounds stay fixed at 2; and a guide requiring a requirement statement drops the missed count in the 24-defect set to 0 for the first time.

The previous lesson measured the work item's chain and showed that the review link's
length comes from round count. What lengthens the round is what could not be seen in the
first round; so is there a kind of finding that does not need to be seen in the first
round at all? There is: **if the author already knows, there is no finding at all.**

Someone working inside a team has already learned most expectations in earlier rounds.
Someone coming from outside has not, and relearns the same expectation in their own
rounds. A **contribution guide** is the written text that carries this learning to before
the round. This lesson's question is not what to write in the guide — it is **how many
rounds every written expectation cuts**, and whether there is a place the guide can never
touch at all.

## Where an Expectation Is Learned

An expectation can be learned from three places. **From the guide:** the author reads it
before submitting the change and takes heed. **From a round:** the reviewer writes the
finding, the author fixes it, the change is resubmitted. **From nowhere:** the expectation
occurs to no one and the change merges as it is.

The three do not cost the same. An expectation learned from the guide spends zero rounds;
because the finding is never born, it never enters the review queue at all. An expectation
learned from a round spends at least one round, and every round writes wait onto the
chain. An expectation never learned spends no round but stays as a defect.

The guide's measurable effect is therefore sought in **round count**, not in the number of
defects found. The guide does not open review's eye; it lowers the defects coming into
review. This distinction is the mirror image of the course's second claim: adding an axis
grows **what is found**, the guide shrinks **what comes in**.

The third path — the expectation never learned — has a counterpart in this measurement,
and it is the **unwritten requirement** class. An expectation no one wrote, no one asked,
appears on no axis and is spoken of in no round. The guide's most interesting question is
right here: can a written text touch a class that is never spoken of at all?

## What Can Be Written in a Guide

The guide is not a style text, it is a list of **acceptance conditions**. Every item names
an expectation that, when unmet, gives birth to a review round. A well-written item states
something the author can verify on their own before submitting.

```text
# example contribution guide excerpt — not executed

## Before submitting
- Style: the formatting setting at the repository root must be
  applied; a manual style fix is submitted as a separate change.
- Test: every changed public behavior must have at least one
  verifying test; a test that only repeats the call does not count.
- Documentation: if a public interface changed, the relevant
  document is updated in the same change.
- Requirement statement: the requirement the change meets is
  written in the description field with the work item number and
  a single sentence; if there is an unmet requirement, that is
  also written.

## Review
- A change meets a single requirement.
- A change submitted with an empty description field is not taken
  into review.
```

How items are written determines measurability. "Tests should be meaningful" is not an
item; the author cannot check it before submitting and the reviewer cannot derive a
finding from it. "Every changed public behavior must have at least one verifying test" is
a checkable condition: even if perspective changes, its answer is yes or no. The same
difference shows up in the second section too — "a change submitted with an empty
description field is not taken into review" is a gate and it is enforceable; "descriptions
should be adequate" is a wish.

The first three of the four items are readily recognized: style, test, and documentation
are three of the five review looks at. The fourth item is different, and it is the
measurement's real question. The **requirement statement** asks the author to write what
the change is supposed to do. Review looks at what was written; the guide widens the
surface review can look at by forcing the author **to write the requirement itself.**

The measurement's assumptions:

- **TF8** — The shared setup's 600-line change and 24 defects are used as they are; the
  class distribution and the oracle are the course's constant. `change` is not modified.
- **TF9** — The guide works **before** review: defects in its scope are resolved by the
  author before submitting and never enter review at all. The guide is not an axis; it
  does not find defects, it prevents them from being born.
- **TF10** — The guide's scope is a class list. Four scopes are tried, and each adds one
  class on top of the previous one; the fifth adds the **unwritten requirement** class.
- **TF11** — **All** defects of every class in scope are resolved. This is an upper
  bound; a partially followed guide's effect stays below these numbers.
- **TF12** — Review runs under two assignments: a single reviewer looking at five axes,
  and three reviewers looking at the same axis. Attention is fixed at **12 chunks**, and
  600 lines is 12 chunks; no chunk goes unread.
- **TF13** — The round cycle comes from the shared setup and writes **6 units** of wait
  per round. The round's input is no longer 24, it is the defect count that passes
  through the guide.
- **TF14** — The set's resolution at 24 defects is **1/24**; the smallest measurable
  difference at the round scale is **1 round**, that is, **6 units** of wait.

## Measurement

```python
"""Contribution guide: the review round a written expectation closes.

The guide works before review: defects in its scope are resolved by the
author before submitting. The change and the class list do not change.
"""
SEED = 20260815
AXES = ("interface", "implementation", "test", "documentation", "style")
UNWRITTEN = "unwritten requirement"
CLASSES = AXES + (UNWRITTEN,)
ATTENTION, CHUNK = 12, 50


def rng(seed):
    d = seed % 2147483646 + 1

    def draw(n):
        nonlocal d
        d = (d * 48271) % 2147483647
        return d % n
    return draw


def change(lines, defect_count=24, seed=SEED):
    draw, defects = rng(seed), []
    chunk_count = max(1, lines // CHUNK)
    for i in range(defect_count):
        defects.append({"no": i + 1, "class": CLASSES[draw(6)],
                         "chunk": draw(chunk_count)})
    return {"lines": lines, "chunks": chunk_count, "defects": defects}


def past_guide(d, scope):
    """Defects in the guide's scope are resolved before submitting."""
    return [k for k in d["defects"] if k["class"] not in scope]


def review(defects, chunks, axes, attention=ATTENTION):
    read = set(range(min(attention, chunks)))
    return {k["no"] for k in defects
            if k["class"] in axes and k["chunk"] in read}


def panel(defects, chunks, assignments, attention=ATTENTION):
    found = set()
    for axes in assignments:
        found |= review(defects, chunks, axes, attention)
    return found


def review_rounds(found, defect_count, wait_per_round=6):
    remaining, rounds, wait = defect_count - len(found), 1, wait_per_round
    while remaining > 0 and rounds < 6:
        rounds += 1
        wait += wait_per_round
        remaining -= max(1, len(found) // 2)
    return rounds, wait, max(0, remaining)


FULL = set(AXES)
GUIDES = {
    "no guide": set(),
    "style written": {"style"},
    "style, test": {"style", "test"},
    "style, test, documentation": {"style", "test", "documentation"},
    "three + requirement statement": {"style", "test", "documentation", UNWRITTEN},
}
ASSIGNMENTS = {"single reviewer, all axes": [FULL],
               "three reviewers, same axis": [{"implementation"}] * 3}
d = change(600)
distribution = {s: sum(1 for k in d["defects"] if k["class"] == s) for s in CLASSES}
print("class distribution: " + ", ".join(f"{s} {n}" for s, n in distribution.items()))

for assignment_name, assignment in ASSIGNMENTS.items():
    print()
    print(assignment_name)
    print(f"{'guide scope':<28s} {'resolved':>8s} {'entering':>8s} "
          f"{'found':>7s} {'missed':>5s} {'unwritten':>10s} {'rounds':>3s} "
          f"{'wait':>7s} {'remaining':>5s}")
    for name, scope in GUIDES.items():
        entering = past_guide(d, scope)
        b = panel(entering, d["chunks"], assignment)
        missed = [k for k in entering if k["no"] not in b]
        unwritten = sum(1 for k in missed if k["class"] == UNWRITTEN)
        rounds, wait, remaining = review_rounds(b, len(entering))
        print(f"{name:<28s} {24 - len(entering):8d} {len(entering):8d} {len(b):7d} "
              f"{len(missed):5d} {unwritten:10d} {rounds:3d} {wait:7d} {remaining:5d}")
```

```
class distribution: interface 3, implementation 6, test 3, documentation 3, style 7, unwritten requirement 2

single reviewer, all axes
guide scope                  resolved entering   found missed  unwritten rounds    wait remaining
no guide                            0       24      22     2          2   2      12     0
style written                       7       17      15     2          2   2      12     0
style, test                        10       14      12     2          2   2      12     0
style, test, documentation         13       11       9     2          2   2      12     0
three + requirement statement       15        9       9     0          0   1       6     0

three reviewers, same axis
guide scope                  resolved entering   found missed  unwritten rounds    wait remaining
no guide                            0       24       6    18          2   6      36     3
style written                       7       17       6    11          2   5      30     0
style, test                        10       14       6     8          2   4      24     0
style, test, documentation         13       11       6     5          2   3      18     0
three + requirement statement       15        9       6     3          0   2      12     0
```

## Reading the Rounds

The two tables measure the same guides under two separate reviews, and the results are
polar opposites.

**In the narrow review** — three reviewers looking at the same axis — the guide cuts one
round for every class added: **6, 5, 4, 3, 2**. Wait drops from **36** to **12**; two-thirds
of it goes away. The found column, though, stays at **6** in all five rows. The guide did
not get even one more defect found; it only reduced what the rounds had to consume and
ended the loop earlier.

**In the wide review** — a single reviewer looking at all five axes — the first four rows
are the same at **2 rounds / 12 wait**. Even as scope climbs to three classes, round count
does not budge. The reason is on the table's left: in this review, missed is already fixed
at **2** and the loop finishes on the second round; there is no round left to cut. Here the
guide reduces not the round but **the work inside the round** — entering drops from **24**
to **11**, found from **22** to **9**.

The wide review's fifth row breaks this fixedness: round drops to **1**, wait to **6**.
This is the only configuration in the course that closes in one round. The reason reads
from the table — missed is **0**. The loop only moves to a second round if a defect
remains; if none remains, the first round is the approval and the work is done.

A two-sentence conclusion follows from this. **A contribution guide buys rounds where
review is narrow; it reduces work where review is wide.** Both gains are real but they are
not the same thing, and looking at the same number will not show it: the first is read in
the wait column, the second in the entering column.

The gap between the first row's **6 rounds / 36 wait / 3 remaining** and the second row's
**5 rounds / 30 wait / 0 remaining** is also worth noting. Writing a single class into the
guide did not just cut one round; **it also zeroed the remaining defect.** Because the loop
finished before hitting the six-round limit, no unclosed defect was left. The previous
lesson's **50**-unit reopening cost vanishes in this row.

## The Guide Reaching the Unwritten

The fifth row shows something else for the first time across the course. The **unwritten
requirement** class has stood with **2** missed in every configuration up to now; here,
**0**. The total missed also drops to **0** in the wide review — this is the only row in
the 24-defect set where missed is zeroed.

The reason for this is not that an axis finally looks at that class. The axis list did not
change; no reviewer is looking anywhere new. What changes is **the defect's class.** When
a requirement statement is required, the author writes into the text what the change is
supposed to do; what was unwritten becomes written, and now it stands on a surface review
can look at.

This is the course's fourth reading's only real counterexample, and it does not refute the
reading, it defines its limit. **No axis sees the unwritten** is true; the remedy is not
changing the axis, it is **making the unwritten get written.** A mechanism standing outside
the review process — a guide item — turns a class review cannot see into a class review
can see.

Note the measure's resolution: two defects are **2/24** in the 24-item set. This is twice
the set's smallest unit and is defensible. A one-defect difference would not be defensible
with this set.

## The Moment the Guide Is Read

The measurement gives an upper bound. **TF11** assumes all defects of every class in scope
are resolved; in reality the compliance rate is below this, and the gains in the table
shrink in the same proportion. If half the style defects were resolved, resolved would be
**3** or **4**, not **7**, and the narrow review's round might stay at **6** instead of
**5**. The guide's value depends less on the content of the text than on **how much of it
is followed.**

What determines the compliance rate is where the guide is read. A text standing at the
repository root, read once, is far from the moment of submitting; when that moment comes,
the item is not remembered. The same item appearing as a checklist on the submission
surface makes the text get read again at every submission. The two carry the same sentence
and do not give the same result.

The second determinant is the item's verifiability. An item the author cannot check on
their own gets skipped; a skipped item does not just lose its own gain, it also weakens
the reading habit for the whole list. This is why lengthening the guide can work in the
opposite direction: in a forty-item list, the share of items followed is lower than in a
four-item list.

The measurement gives a threshold for this. The smallest effect an item shows in the
table is **1 round**, that is, **6 units** of wait. An item that changes neither round nor
entering count in any scope takes up room in the guide and has no measurable payoff.

## What the Guide Cannot Close

The fifth row drops missed to **3** in the narrow review too, but does not zero it. The
three remaining defects stand in axes other than `implementation` and are outside the
guide's scope: the **interface** class was closed by no guide item in either table.

There is a reason for this. A guide can write expectations the author **can verify on
their own.** Whether a style setting was applied, whether a test exists, whether
documentation was updated — all three can be checked alone before submitting. Whether an
interface decision is correct can only be judged by someone else; it has no form that can
be written into a guide, because it requires not an acceptance condition but **judgment.**

The boundary is therefore sharp: **the guide closes checkable expectations; axes requiring
judgment stay in review.** Padding the guide does not cross this boundary, it only produces
an unread text, and an unread item cuts no round; this row's value, invisible in the table,
is always **0 rounds.**

## Summary

- A **contribution guide** carries the expectation to before the round: defects in its
  scope never enter review at all. The guide is not an axis; it does not grow what is
  found, it shrinks what comes in.
- In a narrow review, as guide scope grows, round drops as **6, 5, 4, 3, 2** and wait
  falls from **36** to **12**; found stays at **6** in all five rows.
- In a wide review, round is fixed at **2** for the first four rows; there the guide
  reduces not round but work — entering drops from **24** to **11**, found from **22** to
  **9**.
- Writing a single class drops the remaining defect from **3** to **0** in the narrow
  review and eliminates the previous lesson's **50**-unit reopening cost.
- A guide requiring a **requirement statement** drops the **unwritten requirement** missed
  count from **2** to **0** — because the class moves onto a surface review can see, not
  because a new axis was added.
- The guide closes only expectations the author can verify alone; axes requiring
  judgment, like **interface**, stay in review under every scope.

## Next Step

The guide writes not who does what but **what will be met**. Once the change is
submitted, one more question is born: **who will look?** In some repositories this
question is open; in some it is answered by a rule bound to the file path — a directory
has an owner, and every change touching that directory waits on the owner's approval. The
next lesson measures this rule: do **code ownership** and **required reviewer** grow or
narrow axis diversity? Does raising the required reviewer count to three grow what is
found — or does the course's second claim show up here in reverse?
