Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 107 additions & 1 deletion skills/stage-chapters/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,113 @@ This skill scopes review to *committed* work. If the user has uncommitted change

## Step 3 — Cluster + narrate

> **TODO:** See Issue 11 for the chapter generation prompt port. For now, leave this step as a placeholder. The next revision of this skill will produce a `chapters` array shaped per the schema documented in Step 4.
Using the full diff from Step 2, produce a `chapters` array. Each chapter groups related hunks into a coherent story beat, narrates them for a reviewer unfamiliar with this part of the codebase, and flags judgment calls that need human input.

### 3a — Clustering rules

Group hunks by **causal relationship** — changes that set up or enable later changes belong together.

- Spanning multiple files is expected and correct (e.g., schema + API + UI for one feature = one chapter).
- Moves and refactors are a single chapter — when code is removed from one file and added to another (or a file is deleted and a similar one created), group the deletion and addition hunks together as one "Move/Refactor" chapter, not separate "Remove" and "Add" chapters.
- Split only when changes are truly independent — a reviewer could understand one without knowing about the other.
- Tests belong with their implementation chapter.
- Config/dependency changes can be their own chapter if unrelated to a feature chapter.

**Chapter ordering:**

1. Foundation first: types, interfaces, schemas, utilities that others depend on
2. Core logic next: main implementation
3. Integration last: wiring, configuration, tests

Consider symbol dependencies between chapters — a chapter that introduces a type another chapter uses must come first.

**Hunk ordering within a chapter:**

- Group all hunks from the same file together — do not interleave hunks from different files.
- Within the same file, list hunks in ascending `oldStart` order (matching file layout).

### 3b — Self-validation rules

Every hunk in the diff **must** appear in exactly one chapter. No hunk may be omitted and no hunk may appear in more than one chapter.

Identify each hunk by its exact `(filePath, oldStart)` tuple from the unified-diff `@@ -X,Y +A,B @@` header. Use the EXACT `oldStart` value from the `@@` header — do not recount lines yourself.

- `filePath` is the path after `b/` in the `diff --git a/... b/...` line.
- `oldStart` is the `X` in `@@ -X,Y +A,B @@`. For newly created files the header is `@@ -0,0 +1,N @@`, so `oldStart` is `0`.

After building the chapters array, verify:
1. The total number of `hunkRefs` across all chapters equals the total number of `@@` headers in the diff.
2. Every `(filePath, oldStart)` pair from the diff appears in exactly one chapter's `hunkRefs`.

### 3c — Narration rules

Write each chapter as a story beat — a meaningful step that moves the branch forward, not a summary of files changed.

- **Title:** action-oriented verb phrase, max 8 words (e.g., "Wire org ID through the API layer"). No filler like "Add support for".
- **Summary:** 2–3 sentences covering what this chapter enables and why. Lead with impact, then connect to the broader purpose. When a chapter builds on a previous one, open with that causal link explicitly (e.g., "Now that X is in place…").
- Keep paragraphs short. Prefer splitting distinct points into separate short paragraphs (separated by a blank line) rather than writing one long dense paragraph. Each paragraph should convey a single idea.
- Markdown allowed: `**bold**` for emphasis, `*italics*` for nuance, `` `backticks` `` for inline code references, and fenced code blocks when a short snippet (≤ 6 lines) helps illustrate the change.

### 3d — Key change rules

Key changes are **judgment calls only a human reviewer can make** — things that require product context, team conventions, or knowledge of the author's intent. Linters, type checkers, and code-review bots already cover correctness and style; skip anything they can catch. Ignore auto-generated files.

Return an **empty array** when nothing needs human input — do **not** invent items to fill the list. When a chapter is a straightforward rename, type fix, or mechanical refactor with no judgment calls, `keyChanges` should be `[]`.

Frame each item as a **question**.

Each key change includes `lineRefs`: one line range per distinct spot the question depends on. Most questions touch a single location, so use one range; only add more when the judgment genuinely spans related code in different places.

- Use OLD-column line numbers for `side: "deletions"` (left side of the diff).
- Use NEW-column line numbers for `side: "additions"` (right side of the diff).
- Keep ranges tight — point to the specific lines the question is about, not the entire hunk.
- `startLine` and `endLine` must both be positive integers with `endLine >= startLine`.

**Good examples:**

- "Should `retryCount` reset when the user switches orgs?"
- "Is a 60-minute session timeout appropriate for this user base, or would 30 minutes be safer?"
- "Does this new index cover the query patterns the team actually uses in production?"

**Bad examples:**

- "Check that the auth logic is correct." — vague, verifiable by reading the code
- "The function now handles errors." — changelog item, not a question
- "Make sure the tests pass." — CI catches this, not a human judgment call

### 3e — Output format

Produce an array of chapter objects. Each chapter:

```jsonc
Comment thread
dastratakos marked this conversation as resolved.
{
"id": "chapter-1", // unique within the run, e.g. "chapter-1", "chapter-2", …
"order": 1, // positive integer, 1-indexed
"title": "Short imperative title",
"summary": "Why this chapter matters to the reviewer.",
"hunkRefs": [
// one entry per hunk in the chapter
{ "filePath": "path/to/file.ts", "oldStart": 42 }
],
"keyChanges": [
// zero or more judgment-call questions
{
"content": "A judgment-call question for the reviewer.",
"lineRefs": [
{
"filePath": "path/to/file.ts",
"side": "additions",
"startLine": 50,
"endLine": 55
}
]
}
]
}
```

- Do **not** invent `hunkRefs` — only use `(filePath, oldStart)` tuples that actually appear in the diff's `@@` headers.
- `keyChanges[].lineRefs` must have at least one entry per key change.

## Step 4 — Write JSON file

Expand Down
Loading