# Ordering guide

How to arrange a pull request's changed files into a reading order for reviewers. It applies to people using arrange mode and to AI agents, which receive this page from the `get_ordering_guide` tool.

The goal: a reviewer who reads top to bottom always meets a piece of code after the things it depends on, and understands why each group of files changed.

## Workflow for agents

1. Call `get_pull_request` with the owner, repo and number. It returns every changed file, the current saved order (if any) and its `version`, and `repoConventions` when the repository has a `.github/logikflow.md` file. **Follow the repository's conventions: where they conflict with this guide, they win.** Add their checklist items to the most relevant section.
2. Understand the change. If you are running inside a checkout of the repository, read the diff and the surrounding code there (for example `git diff <base>...<head>`); that gives far better results than patches alone. Otherwise call `get_pull_request` again with `include_patches: true`. Files with more than one change also carry `changes`, with an `id` for each change; you need these only to [split a file across sections](#splitting-a-file-across-sections).
3. Build the order following the rules below: an [overview](#overview), [sections](#sections) with a `layer`, and files in dependency order. Use the [reading hints](#reading-hints) on each file to check yourself.
4. Call `save_reading_order` with `base_version` set to the `version` you received (0 when there was no order). If it reports missing or unknown paths, fix the list and save again. If it reports a conflict, someone else saved in the meantime: fetch again, and only overwrite if the user wants that.
5. If the result lists `suggestions`, apply the ones that fit and save once more with the new `version`. One revision is enough: see [Suggestions](#suggestions).
6. Tell the user the review link returned by the save.
7. Follow the save result's `nextStep` about a diagram. Diagrams are optional: see [Diagrams](#diagrams).

## Ordering rules

Order by dependency: a file comes after the files it uses, before the files that use it. When there is no dependency between files, use these layers, top to bottom:

1. **Contracts and switches**: feature flags, remote config, constants, API schemas, database migrations, public interfaces, event names.
2. **Models and types**: data classes, DTOs, enums, type definitions.
3. **Core logic and utilities**: pure functions, parsers, algorithms, helpers the rest builds on.
4. **Storage and data access**: repositories, caches, persistence, network clients.
5. **Application logic**: controllers, services, view models, use cases, state holders.
6. **Presentation**: views, components, adapters, screens, templates.
7. **Wiring**: dependency injection, routing, entry points, platform glue that only connects the pieces above.
8. **Resources**: layouts, drawables, styles, strings, dimensions, assets, translations. Put the main screen layout before the small pieces it includes.
9. **Build and tooling**: build scripts, CI, lint config, generated files, lockfiles.

A section can name its layer with `layer`: `contracts`, `models`, `logic`, `storage`, `app`, `ui`, `wiring`, `resources` or `tooling`, in that order. Reviewers see it next to the section title, and the save checks that layers come in order.

Tests go directly after the file they test, not in a separate block at the end, unless a test covers many files at once; then put it after the last of them.

Other rules:
- Deleted files go next to the file that replaced them, so the reviewer compares old and new together.
- A renamed or moved file with no real changes goes in the Build and tooling section or the last section.
- If one file is the heart of the change, it may come first with a note, even if it depends on small files; say so in the section note.
- Every changed file appears exactly once, unless you split it (below). Do not invent paths.

## Reading hints

`get_pull_request` adds up to three hints to a file when it can work them out. They come from paths and from the import lines visible in the diff, so treat them as a starting point and confirm against the code.

- `dependsOn`: changed files this file imports. A file should come after everything in its `dependsOn`, unless a note says why not. Imports that didn't change aren't in the diff, so the list can be incomplete.
- `testOf`: the changed file this test covers, from naming conventions such as `foo.test.ts`, `FooTest.kt`, `test_foo.py` and `foo_test.go`. Put the test directly after that file.
- `likelyGenerated`: a lockfile, or minified, vendored or generated output. Label it `generated`.

## Overview

Write an `overview` of two or three sentences. Reviewers read it before the first section, it opens one-change mode, and it goes into the pull request comment. Say:

1. what the change does, in one sentence that isn't the pull request title;
2. the reading path: "Start with the flag and migration, then the service, then the dialog";
3. where the risk is, or what to read slowly: "The retry loop in `InviteService` is the part to check."

Skip it only for a tiny pull request where the section notes already say everything.

## Sections

Group the files into 3 to 8 sections. A very small pull request (under 5 files) can use one section or none.

- **Title**: a short noun phrase naming what the group does in this change, such as "Feature flag and schema" or "Invites are stored per team". Not a file type ("Kotlin files") or a layer name alone ("Models"). Read your titles top to bottom: together they should tell the story of the change.
- **Layer**: the layer from [Ordering rules](#ordering-rules) this section belongs to, when one fits. Reviewers see it as a label next to the title.
- **Note**: one to three plain sentences saying what changed and why, and anything the reviewer should keep in mind. When it isn't obvious, open with how this section builds on the previous one: "Uses the `invitedAt` field from Part 1." Name concrete classes, functions or flags in `backticks`. Don't restate the file list.

## File notes

Add a note to a file only when it helps the review: a non-obvious reason, a risk, a follow-up, or "mechanical rename, skim". Most files need no note. Keep notes to one or two sentences.

Reviewers can step through a pull request **one change (diff hunk) at a time**, and they see the file's note above every change in that file. When a file holds several unrelated changes, say so in the note and name them in the order they appear, for example: "Two changes: the new `invitesEnabled` check, then the rename of `listMembers`." If those changes belong to different sections, split the file instead.

## Splitting a file across sections

Sometimes one file holds changes that belong to different parts of the story, such as a new model field near the top and the screen code that uses it further down. You can split that file so each part appears in the section it belongs to.

Split only when it really helps. Most files should stay whole: a reviewer reads a file more easily in one place. Good reasons to split:

- a shared file (a router, a strings file, a DI module, a large view model) that gets small unrelated additions for several features in the pull request;
- one change in a file is a prerequisite that has to be read early, and the rest only makes sense later.

How to split:

1. Take the change IDs from `files[].changes` in `get_pull_request`. Only files with two or more changes have them.
2. List the file once in each section where part of it belongs, with `hunks` naming the changes for that part, in any order. Each change goes in exactly one part.
3. Optionally, list the file once more *without* `hunks`. That part takes every change you didn't name, including changes from commits pushed later. Without it, every change must be named, and later changes join the first part.

Each part can have its own `note`, `checks` and `focus`. Give each part a short note saying what that part does, for example "Part 1: the new `invitedAt` field; the screen that shows it is in *Invite dialog*."

Change IDs come from each change's content, not its line numbers, so they stay the same when other changes move the lines around. If a part names an ID that no longer exists, the save is rejected with the current IDs to use.

## Focus labels

A file can carry one focus label:

- `key`: the heart of the change, where most of the review effort should go. Use it for one to three files, never most of them. Every key file needs a note saying what to look for; a key label without one tells the reviewer to read carefully but not what for.
- `skim`: mechanical or low-risk, such as renames, string changes and simple wiring.
- `generated`: generated, vendored or lock files. They start collapsed for reviewers.

Leave most files without a label.

## Checklists

Checklist items tell the reviewer what to verify. Add them to a section or file when there is something specific and checkable:

- Good: "With the flag off, the list is identical to before", "`acceptInvite` also closes the invite", "Back button closes the dialog before the page".
- Bad: "Code looks good", "Check for bugs", "Review this file".

Use 0 to 4 items per section and at most one or two per file. Keep each item under 120 characters.

## Suggestions

`save_reading_order` saves first, then checks the order against this guide. The result's `suggestions` list what would make it easier to follow: a section titled with a layer name, a key file without a note, more than three key files, a vague checklist item, a test placed before the file it covers, a file placed before one it imports, a generated file without its label, a missing overview, and similar. Nothing in the list blocks the save, and `get_pull_request` shows the same list for the current order.

Apply the suggestions that fit and save once more with the returned `version`. Skip one when you have a reason, and put the reason in the note it concerns. One revision is enough; don't loop.

## Diagrams

A diagram is an optional picture of how the pieces of the change connect. Reviewers open it from the **Diagram** tab, and each box can open its file or one exact change. Save one with `save_diagram`; it never touches the reading order.

### When to draw one

Follow `nextStep` from `save_reading_order` and the repository's `diagramPreference` from `get_pull_request`:

- `never`: don't offer or draw one.
- `always`: draw one for every pull request, without asking.
- `ask` (the default): after saving the order, ask the user once whether they'd like a diagram, unless the pull request is small (under 4 files) or they already answered in this conversation. Draw one only if they say yes, or they asked for one in the first place.

A diagram helps when behaviour flows across several files: a request passing through layers, an event and what reacts to it, a state machine, a fallback path. Skip it for renames, dependency bumps, copy changes or a pull request that is mostly one file.

### How to draw a good one

- **4 to 20 nodes.** One node is one step or one piece in the flow, not one file. Leave out files that don't take part in the flow (tests can be one node per behaviour they cover).
- **Titles are short verbs or nouns:** "Check cycle", "Queue outer boundary", "Invite model". Up to 80 characters; 2 to 4 words is best.
- **`kind`** sets the colour and icon:
  - `trigger`: where the flow starts, such as a user action, event, request or cron job.
  - `logic`: code that decides or transforms.
  - `decision`: a branch point.
  - `data`: models, storage, caches, migrations.
  - `ui`: screens, views, components.
  - `test`: tests that cover part of the flow.
  - `config`: flags, settings, build and wiring.
  - `external`: services and libraries outside the repository.
  - `warning`: a fallback, error path or known risk.
- **`lines`** add up to 4 short `label: text` rows. Useful labels are `change` (what this pull request changes here), `role`, `example`, `returns` and `why`. Keep each under 80 characters and wrap code in backticks.
- **`file`** links the node to a changed file. Add **`hunk`** with an id from `files[].changes` to point at one change. Only use paths and ids from `get_pull_request`.
- **Edges** go in the direction things happen or depend: caller to callee, event to handler, code to the test that covers it. Label them with 1 to 3 words ("walk graph", "covered by", "on error"). Use `dashed: true` for optional or indirect links.
- **Groups** (up to 12) draw a box around nodes that belong together, such as "Server", "Client payload" or "Regression coverage". Use the same names as your sections when they match.
- Give the diagram a `title` that says what it shows, such as "How an invite is accepted".

The layout is automatic, left to right, so you only describe the pieces and how they connect. Base `base_version` on `diagramBaseVersion` from `get_pull_request`. When the user asks to redraw, fetch again, start from `currentDiagram.diagram` and change what's needed.

## Style

Write for a busy reviewer: short, specific, no filler, no marketing tone, no emoji. Use the terms the code uses.
