agentleFS
rikvanrielrikvanriel/code-hygiene/skills/change-splitting/SKILL.md

change-splitting

Skill2 starsChanged 56 days agoMITView on GitHub

Use when committing or splitting a large change — tests whether it splits into easy-to-review smaller changes: mixed subjects, mechanical change, buried helper, broken bisect.

The file

We split this skill into the rules it gives an agent

8 rules. About 0 are common, 7 are distinctive, and 1 is very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈7

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 1

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Don't over-split: 500 edits one file as 500 commits is its own error.

    line 23
  2. Distinctive:

    When single source file ≥200 changed lines, examine for separable seams — examination required, not auto-split:

    line 27
  3. Distinctive:

    Document examination even when keeping together.

    line 34
  4. Distinctive:

    When series/PR stack covers multiple themes, keep same-theme consecutive where dependencies/bisect allow, reviewer stays in context.

    line 43
  5. Distinctive:

    Check: git log --oneline -20 grouping by keyword — would reviewer need to jump mental model back and forth?

    line 45
  6. Distinctive:

    Before accepting N patches is ceiling because shared caller infra must change all at once, try narrowing:

    line 49
  7. Distinctive:

    Keep old output channel alive unreached for not-yet-migrated callers

    line 51
  8. Very specific:

    Never introduce bug in one patch fixed later same series — squash, note after --- if needed.

    line 65

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Change Splitting — One Logical Change Per Unit

Capability: reviewer can understand, build, test each unit in order without context-switching themes.

GC-30 — One logical change per commit/PR

  • One logical change spanning many files = one commit.
  • Two subjects same file = two commits (avoid "please split this up, don't mix SoC with evm stuff").
  • Distinct transformation buried in larger one = own commit.
  • Don't over-split: 500 edits one file as 500 commits is its own error.

GC-31 — 200-line trigger to examine for seams

When single source file ≥200 changed lines, examine for separable seams — examination required, not auto-split:

  • Mechanical interface/type conversion vs behavioral change riding on top
  • Code moved unchanged vs rewritten
  • Case already handled correctly needing result reported differently vs genuinely new algorithm
  • Helper extracted vs first caller of that helper

Document examination even when keeping together.

Verification:

git diff --numstat HEAD~1 | awk '$1+$2 >= 200 {print}'  # --numstat puts added/deleted counts in $1/$2; --stat does not

GC-32 — Thematic grouping, not interleaving

When series/PR stack covers multiple themes, keep same-theme consecutive where dependencies/bisect allow, reviewer stays in context. Counterpart to split-by-theme per-patch rule.

Check: git log --oneline -20 grouping by keyword — would reviewer need to jump mental model back and forth?

GC-33 — Incremental narrowing — parallel old and new

Before accepting N patches is ceiling because shared caller infra must change all at once, try narrowing:

  • Keep old output channel alive unreached for not-yet-migrated callers
  • Introduce new path for migrated ones
  • Retire old only after all migrated

Standard introduce-new / migrate-one-at-a-time / remove-old. What often separates real ceiling from premature.

GC-34 — Bisectable, builds on own

Every intermediate:

  • Builds
  • Passes existing tests / boots minimal
  • Behaviorally coherent (no leak until later, no unbalanced refcount alone, no last-use removed N and symbol N+1 — keep same patch or order so nothing dangles)

Never introduce bug in one patch fixed later same series — squash, note after --- if needed.

GC-35 — Cover letter / PR description owns ordering

State cross-patch ordering, prerequisites, dep notes in cover letter / PR description, not mechanics block middle of log going into history. Number patches N/M so order unambiguous.

GC-36 — A rename, a removal or a bulk edit is complete only when nothing points at the old name

A rename, a moved file, an extracted helper, a changed flag, a removed key or field: the change is finished when every reference has been updated — code, tests, docs, config, examples, comments — and every touched file still parses. Grep the whole tree for the old name rather than fixing the call sites that compiled loudly: the ones that fail silently (a string in a config, a name in documentation, a dynamic lookup) are exactly the ones a compiler will not find. Report the grep you ran and its result as the completion evidence.

A removal carries the reverse obligation: nothing may still ASSERT what was removed. A docstring promising a key the function no longer returns, or a comment justifying its own field by a diagnosis that was retracted elsewhere, is the same defect as a dangling call — the reader is sent after behaviour that does not exist. comment-quality GC-23 owns how the surviving text is worded; scripts/check-comment-drift.py reports the survivors mechanically.

4Q gate

(a) What's wrong? Does split mix subjects, break bisect, hide transformation, 200-line trigger unchecked without seam analysis? (b) Better way? Sweep N=2,3,4... concrete splits named patches scope dep order each builds. Materially better grouping? State explicitly if none beats with tradeoff correctness/simplicity/cost. (c) Missing? Rollback if middle reverted, ownership transfer, non-interference test suite name, failure notification if bisect fails, what unblocks downstream, what stays out of scope (non-goals with reason). (d) Boundaries explicit? CONTRIBUTING found for subject/trailer style, external dep version pinned, irreversible schema/migration guarded, scope positive: provides reviewable units so reviewer stays in context, not "not interleaved".

Converged = one full iteration no new finding across all 4. Trend shrinking -> keep going. Recurring same scale -> wrong altitude rescope.

Verification

./scripts/check-hygiene.sh HEAD
./scripts/phases.py --phase 2 --profile full 2>&1 | tail -n 20
# Churn check: per-commit summed additions vs series-net per file.
# sum+ >> net+ means an early patch introduced code a later patch
# removed — squash candidate (GC-34: never introduce-then-fix in-series).

Related

  • changelog-quality GC-10..GC-17 owns subject/body
  • code-structure owns helper extraction by theme — this owns when extraction is own patch
  • project-discovery Step0 finds upstream splitting convention
  • factual-integrity owns never invent — cover letter claims verified vs actual patches

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

Reviews can't be read right now.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.