examples/before-after.md
# refactor-ruthless-editor — worked example: a PR body, cut
## Before (180 words)
> It is worth noting that this pull request contains the results of a refactoring pass that was
> performed on the parser module. In this PR, changes were made to the `parseHeader` function by
> the refactoring pipeline in order to simplify its structure. The function was previously very
> long and fairly complex, weighing in at 122 lines, and it has now been split into three smaller,
> more focused functions: `readMagic`, `readFields`, and `validateHeader`. All 38 of the existing
> tests continue to pass, which means that the behavior has been comprehensively preserved. It
> could be argued that further simplification is possible in the future. Additionally, it should
> be mentioned that one test, `header_fuzz_case_9`, was already flaky before this change; it was
> skipped rather than fixed, and this is tracked as a parked item. To summarize, this PR splits
> `parseHeader` into three functions, keeps all tests passing, and parks the flaky test. Please
> run `npm test` before merging to confirm the results on your machine.
## Fact inventory (extracted before cutting)
1. Refactor of parser module / `parseHeader`
2. Was 122 lines; split into `readMagic`, `readFields`, `validateHeader`
3. All 38 existing tests pass — behavior preserved
4. `header_fuzz_case_9` was flaky BEFORE the change; skipped, not fixed; parked item
5. Instruction: run `npm test` before merging
## After (118 words, −34%)
> Refactor of the parser module: `parseHeader` (122 lines) is split into three focused functions —
> `readMagic`, `readFields`, and `validateHeader`.
>
> All 38 existing tests pass; behavior is preserved.
>
> One caveat: `header_fuzz_case_9` was flaky before this change. It is skipped, not fixed, and
> tracked as a parked item.
>
> Before merging, run `npm test` to confirm on your machine.
## Edit log (why each cut was safe)
| Cut | Category | Why no loss |
|---|---|---|
| "It is worth noting that… In this PR…" | throat-clearing | carried no facts |
| "changes were made … by the pipeline" | passive detour | rewritten active, same claim |
| "very long and fairly complex" | empty hedges/adjectives | the number 122 already says it |
| "comprehensively" | non-working adverb | "preserved" unchanged |
| "It could be argued that further…" | empty hedge | asserted nothing actionable |
| "To summarize, this PR splits…" | duplicate | every fact already stated once |
## Inventory check after edit
1 ✓ · 2 ✓ · 3 ✓ · 4 ✓ (flaky-before caveat kept word-for-word in spirit and substance) · 5 ✓.
Code spans (`parseHeader`, `npm test`, test name) byte-identical. Zero information loss.
references/method.md
# refactor-ruthless-editor — full method: the cutting rules
One principle: **a sentence stays only if it changes what the reader does or knows.** The edit changes length, never meaning.
## What is in scope
Prose the pipeline emits: the final write-up, shipping artifacts, PR bodies, reports, retro
summaries, README additions the chain drafted. **Out of scope, always:** source code, config,
tests, data files, fenced code blocks inside prose, `identifiers` and paths in backticks, direct
quotes, and any span the user asked to keep verbatim (check state notes for keep-verbatim flags).
## The fact inventory (do this FIRST)
Before touching a word, list every unit of information the draft carries:
- claims ("the build was green before and after")
- numbers and measurements ("38 files", "p95 214ms")
- file paths, commands, identifiers
- decisions and their reasons ("kept the legacy adapter because X depends on it")
- caveats, risks, open items ("the flaky test was skipped, not fixed")
- instructions to the reader ("run the migration before deploying")
This list is the loss detector. After editing, every entry must still be findable in the text.
If one is missing, revert the cut that removed it — do not re-add the fact from memory, because
memory paraphrases and paraphrase drifts.
## Cutting passes (in order — one category at a time)
1. **Throat-clearing.** Openers that delay the point: "It is worth noting that", "In this section
we will", "As mentioned above". Delete; start at the point.
2. **Empty hedges.** Hedges that assert nothing ("somewhat", "fairly", "it could be argued").
Distinguish from real caveats — a hedge that encodes genuine uncertainty is a fact; keep it.
3. **Duplicates.** The same point made in the intro, the body, and the summary. Keep the strongest
occurrence (usually the one with the evidence attached); cut the rest.
4. **Non-working adjectives/adverbs.** "Comprehensive", "robust", "simply", "very". If deleting
the word changes nothing, it was doing nothing.
5. **Passive detours.** "Changes were made to the parser by the chain" → "The chain changed the
parser." Shorter and clearer, same claim.
6. **Heading echoes.** Sentences that restate the heading above them. The heading already said it.
7. **List compression.** Prose enumerations ("first… second… third…") become bullet lists when
that is shorter; bullets that share a stem get the stem factored out.
Passes are ordered from safest to most structural. Stop early rather than force a rewrite —
a full rewrite is exactly the over-eager behavior this pipeline bans elsewhere for code, and the
same rule applies to prose.
## The 30% target
Typical pipeline drafts shed 25–40% without loss. Treat 30% as the expectation, not a quota. **A first-draft pass that sheds under ~20% was almost certainly timid — run it again before accepting; models under-cut their own prose far more often than they over-cut it.**
- A draft already tight at 10% savings: take the 10% and say so.
- A bloated draft offering 50%: take it, but re-verify the inventory extra carefully.
- Never cut a fact to reach a number. Information loss is a defect; length is only a preference.
## Verification protocol
1. Run `scripts/checklist.mjs --measure <before> <after>` → words before/after, reduction %.
2. Walk the fact inventory item by item against the edited text. Tick each.
3. Diff the code blocks / verbatim spans between draft and edit — they must be byte-identical.
4. Record all of it in `templates/output.md`; an edit without a log did not happen.
## Tone preservation
The pipeline speaks calmly and plainly to the person running it. Cutting must not turn calm into
curt: keep the sentence that tells the user their code still works the same, even though a purely
information-theoretic edit might drop it. Reassurance the reader relies on is a fact.
scripts/checklist.mjs
#!/usr/bin/env node
/**
* refactor-ruthless-editor — checklist + reduction meter. Zero deps.
* node checklist.mjs -> prints the step checklist as JSON
* node checklist.mjs --measure <before> <after> -> word counts + reduction % for two text files
*/
import { readFileSync } from "node:fs";
const SKILL = "refactor-ruthless-editor";
const PHASE = "docs";
const STEPS = [
{ id: 1, step: "scope", detail: "Collect this run's prose deliverables; exclude code blocks, identifiers, quotes, keep-verbatim spans." },
{ id: 2, step: "inventory", detail: "List every fact: claims, numbers, paths, decisions, caveats, instructions. This is the loss detector." },
{ id: 3, step: "cut-passes", detail: "Throat-clearing -> hedges -> duplicates -> dead adjectives -> passive detours -> heading echoes -> list compression." },
{ id: 4, step: "measure", detail: "Run --measure before/after; ~30% is the target, never a quota." },
{ id: 5, step: "verify-zero-loss", detail: "Re-walk the inventory; any missing fact reverts its cut (never re-paraphrase from memory)." },
{ id: 6, step: "log", detail: "Fill templates/output.md: stats + edit log + inventory confirmation." },
];
const words = (t) => (t.match(/\S+/g) || []).length;
const argv = process.argv.slice(2);
const mi = argv.indexOf("--measure");
if (mi >= 0) {
const [bf, af] = [argv[mi + 1], argv[mi + 2]];
let outObj;
try {
const b = words(readFileSync(bf, "utf8"));
const a = words(readFileSync(af, "utf8"));
outObj = { skill: SKILL, wordsBefore: b, wordsAfter: a, reductionPct: b ? +(((b - a) / b) * 100).toFixed(1) : 0, target: "≈30%, zero information loss" };
} catch (e) {
outObj = { skill: SKILL, error: `could not read files: ${e.message}`, usage: "--measure <beforeFile> <afterFile>" };
}
process.stdout.write(JSON.stringify(outObj, null, 2) + "\n");
} else {
process.stdout.write(JSON.stringify({ skill: SKILL, phase: PHASE, steps: STEPS }, null, 2) + "\n");
}
SKILL.md
---
name: refactor-ruthless-editor
description: "Use this skill when any prose the refactor-chain pipeline emits — the final write-up, shipping artifacts, PR bodies, reports, retro summaries — needs its cutting pass before it goes out. Trigger phrases include \"tighten the write-up\", \"this report is too long\", \"cut the fluff\", \"edit the PR body\", \"make it shorter without losing anything\", or the orchestrator reaching the docs phase with a draft in hand. This is the docs phase of the refactor-chain pipeline. It edits prose ONLY — never code, never config, never text the user asked to preserve. Target is roughly 30% shorter with zero information loss, and every cut is logged."
---
# Ruthless Prose Edit — refactor-chain · docs
**Bundle:** refactor-chain (self-diagnosing, self-healing fix-it pipeline).
**Phase:** docs · **Prerequisite:** a drafted document (usually from `refactor-write-up` or `refactor-artifacts-sync`) · **Next:** ship.
**Adaptivity / conditional:** repo-agnostic. Applies to every prose deliverable the chain produces; skipped only when there is no prose to edit.
## Purpose
Every document the pipeline writes gets one deliberate cutting pass before it ships. The rule is
simple: a sentence stays only if it changes what the reader does or knows; otherwise it's cut. The target is about 30% shorter with **zero
information loss** — every fact, number, path, caveat, and decision survives; only the padding
dies. Code blocks, identifiers, and anything the user asked to keep verbatim are untouchable.
## When to use
- The write-up, PR body, report, or retro is drafted and about to ship.
- Someone says "tighten this", "too wordy", "cut it down", "edit the PR body".
- The orchestrator enters the docs phase with any prose artifact in state.
- Any pipeline output longer than a paragraph that a human will actually read.
## What I'll tell you (plain-language / ADHD-friendly)
- "Your write-up is drafted — now I'll do the cutting pass. Same facts, fewer words. Nothing you said to keep gets touched."
- "Before I cut anything, I list every fact the draft contains. After cutting, I check the list again — if a fact went missing, the cut is reverted."
- "Done: 412 words down to 279 (32% shorter). Every number, path, and caveat is still there — here's the edit log if you want to see exactly what went."
- "This sentence resisted cutting because it carries a caveat — it stays."
- "I never edit your code or anything you marked as keep-verbatim. Say 'show technical details' for the full before/after diff."
## Method
1. **Scope the text.** Collect the prose deliverables from this run (write-up, artifacts, PR body,
reports). Exclude code blocks, fenced snippets, `identifiers`, quoted user text, and anything
flagged keep-verbatim in state notes.
2. **Inventory before cutting.** Extract the draft's fact list: every claim, number, file path,
decision, caveat, and instruction. This list is the loss detector.
3. **Cut in passes** (full rules in `references/method.md`): throat-clearing openers, hedges that
assert nothing, points made twice, adjectives doing no work, passive detours, summary sentences
that restate the heading. One pass per category beats one heroic rewrite.
4. **Measure.** Run `node scripts/checklist.mjs --measure <before> <after>` for word counts and the
reduction percentage. ~30% is the target, not a quota — stop when further cuts would cost meaning.
5. **Verify zero loss.** Re-walk the fact inventory against the edited text. Any missing fact means
the responsible cut is reverted, not the fact paraphrased from memory.
6. **Log it.** Fill `templates/output.md`: before/after stats plus the edit log — what was cut,
why, and the facts confirmation.
## Guardrails
- **Advisory-only toward code: it never edits code, config, tests, or data — prose deliverables only.**
- Text the user asked to preserve is verbatim-sacred, even if it is wordy.
- Zero information loss is a hard rule: a cut that removes a fact, number, caveat, or step is a bug.
- 30% is a target, not a mandate — a tight draft may only shed 10%; never pad cuts to hit a number.
- Never "improve" meaning while cutting. Editing changes length, not claims.
## Verify
- Plain: "The document says everything it said before, in noticeably fewer words, and I can show you what went."
- Technical: `--measure` reports the reduction; the fact inventory maps 1:1 onto the edited text;
no code block, identifier, or keep-verbatim span differs from the draft; the edit log in
`templates/output.md` accounts for every removed sentence.
## Resources
- `references/method.md` — the full cutting rules, pass order, and the fact-inventory discipline.
- `examples/before-after.md` — a worked edit: 180-word PR body → 118 words, zero loss, with log.
- `scripts/checklist.mjs` — step checklist as JSON; `--measure <before> <after>` for reduction stats.
- `templates/output.md` — the before/after edit-log scaffold.
## Chain position
Runs in the **docs** phase, after `refactor-write-up` and `refactor-artifacts-sync` have produced
their drafts and before `refactor-ship` sends anything out — the last pass any prose gets. It
consumes drafted documents from chain state and feeds the ship phase leaner versions of the same
documents. It never touches the code the chain refactored; `refactor-code-principles` and the review
gate own that lane.
templates/output.md
# Edit Log — <document name>
> Refactor-chain · docs phase · ruthless prose edit · <date>
> Prose only. Code, identifiers, and keep-verbatim text untouched.
## Stats
- Words: `<before>` → `<after>` (**−<pct>%**, target ≈30%)
- Documents edited this run: <list: write-up / artifacts / PR body / report>
- Keep-verbatim spans honored: <count, or "none flagged">
## Fact inventory (extracted BEFORE cutting)
1. <claim / number / path / decision / caveat / instruction>
2. <…>
<!-- every unit of information the draft carried -->
## Cuts made
| # | What was cut (short quote) | Category | Why no information was lost |
|---|---|---|---|
| 1 | "<…>" | throat-clearing \| hedge \| duplicate \| dead adjective \| passive \| heading echo \| list compression | <reason> |
## Cuts refused
- "<sentence kept>" — carries <caveat / reassurance / instruction>; cutting it would lose meaning.
## Zero-loss verification
- Inventory re-check: <N>/<N> facts present in the edited text. <If any reverted: which cut, why.>
- Code blocks / verbatim spans: byte-identical to draft — <yes/no>.
## Before / after (or link to diff)
<the edited document, or where to find the full before/after pair>