[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6K7MGQFFYCD8HFDP1B95KDN":3,"skill-same:01M6K7MGQFFYCD8HFDP1B95KDN":77},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":31,"linkOnly":32,"markdownContent":33,"markdownBody":34,"frontMatter":35,"refName":38,"commitSha":39,"skillDirectory":40,"forksCount":14,"repositoryHtmlUrl":41,"repositoryHomepageUrl":6,"ownerHtmlUrl":42,"ownerBlogUrl":6,"ownerDescription":43,"updatedAt":44,"install":45,"resources":58},"01M6K7MGQFFYCD8HFDP1B95KDN","slop",null,"Find unchosen code — surface area growing without leverage. Use pre-merge on a branch, or to check if a repo is accreting.","joewalnes\u002Fskills","joewalnes","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F48950?v=4","01M6K7J46C00DDV34GMGT2NK72","Joe Walnes","01M6K7J4ANFVAP1P9ZJ3K4F3P2",3,"MIT","https:\u002F\u002Fgithub.com\u002Fjoewalnes\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fslop\u002FSKILL.md",[],[5,19,20,21,22,23,24,25,26,27,28,29,30],"merge","code","explain","find","branch","repo","check","use","leverage","quick","rev","pre-merge","2026-11-10 10:12:30",false,"---\nname: slop\ndescription: Find unchosen code — surface area growing without leverage. Use pre-merge on a branch, or to check if a repo is accreting.\nargument-hint: [branch | rev-range | --explain | --quick]\n---\n\n# Slop\n\nHand-written code was expensive, and the expense did invisible work: it forced planning, forced holding the design in your head, forced choosing the change that gave the most leverage for the least disruption, and forced writing for a reader. AI made lines free, and every discipline the cost was silently enforcing vanished with it.\n\nThe result is two kinds of code. **Hand-written code is the residue of understanding. Slop is the residue of attempts.** Every absence in hand-written code was a decision — no null check means \"I know this can't be null.\" Slop has no absences: every guard that *might* be needed is present, every fallback that *might* help is chained. It encodes uncertainty where good code encodes knowledge, and that is exactly why it's expensive to read — nothing was omitted, so a reader can't tell what matters.\n\n**Slop is unchosen code.** That is the whole test. The signals below detect the absence of choosing.\n\n## What this skill does NOT penalise\n\nGet this wrong and the skill becomes a lint for \"small,\" which is a different and worse thing.\n\n- **A big change is not slop.** A 500-line diff that collapses three renderers into one has a single sentence that accounts for all of it, and the codebase has *fewer* concepts afterward. That is excellent. Size is not the axis.\n- **A single-implementation abstraction is not slop.** A seam with one implementation is good when the interface is *smaller* than what it hides, it isolates a decision the author can *name*, and a second implementation would slot in without touching callers. Same shape on a diagram as \"make it configurable\"; opposite effect on the reader.\n- **A fix that only adds lines is not automatically slop.** Sometimes a case was genuinely missing. The tiebreaker is whether the root cause is stated.\n- **A high add:delete ratio driven by tests, docs and tooling is not slop.** Split additions into production code versus tests\u002Fdocs\u002Ftooling before reading the ratio as accretion — the history script does this. Five hundred lines of regression tests behind a ten-line fix is chosen; five hundred lines of guards is not. (First trial: a 7.5:1 ratio that looked like sediment turned out to be 86% tests and tooling; the production-code ratio was 1.97:1 in both the hand-written and AI eras — identical.)\n\n- **A high fix rate is not slop when fixing is the methodology.** A repo run through adversarial QA rounds (bug IDs like `QA-REG-218`, \"hunting round 48\") will be 30–40% fix commits by construction. The count says nothing; read *where* the fixes concentrate (the hotspot table) and whether each names its cause.\n- **A fix-of-a-fix chain in a hotspot file is not sediment until you've checked it's the same bug.** Three consecutive fixes to `Renderer.pm` on one day were three different bugs — every rendering bug lands in the file where rendering lives. That's a god-file finding (tier 2), not a fix-discipline finding (tier 3). Read the chain before naming it.\n\nIn every case the distinguishing question is the same: **could the author say why?** A change that can be explained, whose explanation accounts for the whole diff, is chosen. Grade intent, not volume.\n\n## The hierarchy — what decides the grade\n\n**1. Articulability (primary — decides).** Can the change be stated as one thesis, and does that thesis account for the whole diff? \"Collapse the three renderers into one\" — yes. \"Fix X, and also handle Y, and add a fallback for Z\" — that's three changes wearing one commit, none of them chosen. For a repo: can anyone say why each module exists?\n\n**2. Surface area and composability (measurable proxy — decides).** The *learning surface* is everything a reader or caller must know: exported names, function parameters, config options and flags, modes and special cases in behaviour, the number of files you must open to understand one thing. Count it before and after. Good changes — large or small — hold it flat or shrink it. Slop only ever grows it. Composability: can the pieces be combined without knowing about each other, or does each new piece special-case the last?\n\nThree surface-area shapes worth measuring directly, because the script can't see them:\n- **God files and god functions, and their trajectory.** Size the files the hotspot table names, at two or three points in history. A 5,000-line file absorbing 60 fixes and growing 20% a quarter is where sediment will form even if every individual commit is chosen. A 400-line function is a reader-load cost regardless of how it got there. But separate production lines from any inline test module first — a 5,000-line Rust file that is 60% `mod tests` is not the god file it looks like.\n- **The tracker itself.** `TODO.md` is part of the learning surface. One with hundreds of *done* items never pruned — thousands of lines a reader must wade through to find what's open — is theory-holder sediment. (`\u002Fscorecard`'s A1 dimension grades the same thing; cite it.)\n- **Docs versus code surface.** If the command palette grew 45% and `FEATURES.md` grew one line, either the new commands are variants of listed features or the doc is behind. Check which.\n\n**3. History trends (evidence — decides in repo mode).** These are the measured signatures of accretion, and `scripts\u002Fslop_history.py` computes them:\n- **Fix commits that delete nothing** — the single strongest signal. A fix that understands finds the wrong thing and removes it; a fix that doesn't wraps the symptom in a guard.\n- **Fix-of-a-fix chains** — the same file, two \"fix\" commits within two weeks.\n- **Churn** — code rewritten within two weeks of being written.\n- **Add:delete ratio** trending up; addition-only commits as a share.\n- **Refactor share** (moves\u002Frenames) trending to zero; **legacy code** never revisited — the codebase grows only at its edges.\n- **Big diff, trivial message** — \"fix typo\" touching 300 lines.\n\n**4. Code smells (weak priors — annotate only, never decide).** Things that are *usually* unchosen. They raise a flag for reading; they do not move the grade on their own:\n- Error-masking: broad `catch`\u002F`except`, swallowed errors, `|| default` chains, optional-chaining everywhere, retries around things that shouldn't fail.\n- Guards against states that cannot occur.\n- Abstractions that grow the surface: an interface bigger than what it wraps, mode flags, options with one caller, a factory that makes one thing, \"configurable\" things never configured.\n- Generic naming: `data`, `item`, `result`, `handle*`, `process*`, `utils`, `helper`, `manager`.\n- Narrating comments (`\u002F\u002F increment the counter`) versus load-bearing ones (`\u002F\u002F see #123: X must precede Y because …`).\n- Long methods, god classes, and the *modular mirage* — files split up but not semantically cohesive.\n- Tests that mirror the implementation, assert a mock was called, or would pass if the code were deleted.\n- New code that reinvents something already in the codebase instead of calling it.\n- **Copy-pasted tests.** Five near-identical test functions asserting the same string with different inputs, where one table-driven test would do. Tests aren't surface area, but repetition in them is still unchosen — and it's where AI output is most repetitive.\n- **Fleet artifacts** (repos run by autonomous agent crews): the same commit landing twice via two branches, tracker entries duplicated by merges and then de-duplicated in a later commit, derived data or build output committed then untracked. Each is small; together they measure how much of a reconciliation role the fleet needs. The script flags duplicate landings.\n\n## Modes\n\n```\n\u002Fslop                    # repo: history trends + a reading of recent flagged commits, graded\n\u002Fslop \u003Cbranch|range>     # diff: pre-merge audit of one change (go-team's gate uses this)\n\u002Fslop --explain          # the Explanation Gate: you explain the change; the skill shows what you missed\n\u002Fslop --quick            # one grade + three lines, for \u002Fscorecard's Accretion row\n```\n\n## The scripts\n\nThree, all Python, all approximate by construction and labelled so. `scripts\u002Fslop_lang.py` holds the per-language patterns (Go, Rust, Perl, Python, JS\u002FTS) the other two share.\n\n- **`slop_history.py \u003Crepo>`** — tier 3. Add:delete (production vs everything), fix commits that delete nothing, fix-of-a-fix chains, the fix-hotspot table, refactor moves, duplicate landings; split hand-written vs AI-attributed, or `--split YYYY-MM-DD`.\n- **`slop_surface.py \u003Crepo> --from REV [--to REV]`** — tier 2. Production LOC with inline test modules separated, public\u002Fexported names, function count, the longest functions, the biggest files, and the delta between two revisions. `--at REV` gives one reading (the compass uses this). This replaces every hand-measurement that went wrong in the first trials.\n- **`slop_diff.py --repo R \u003Cbase>..\u003Chead> [--require-thesis]`** — the pre-merge check, and `\u002Fgo-team`'s gate instrument. **Exit 0** clean (hints may print); **exit 2** *return to worker* with reasons: a fix that deletes no production line and names no `Cause:`; public surface that grows with no `Surface:` trailer; no `Thesis:` trailer (when required); a new function whose name nearly matches an existing one. Hints, never deciding: a subject that reads as several theses, added lines repeated three or more times, generic names. Returned is not failed — the worker answers the question and resubmits.\n\n## Repo mode\n\n1. **Run the script.** `python3 \u003Cskill-dir>\u002Fscripts\u002Fslop_history.py \u003Crepo>`. It splits history into a hand-written era and an AI-attributed era when it can (via `Co-Authored-By` trailers and similar markers) — that comparison, on the same codebase, is the most persuasive evidence there is. Use `--since` to narrow, `--split YYYY-MM-DD` if attribution is missing. Read the **production-code-only** ratio, not the headline one. Changelogs, docs and bug registries are excluded from fix signals automatically; check the exclusion line to make sure it caught the right files.\n   **Attribution is by trailer, not author.** In a repo worked by agents, every commit's author field is the human — agents commit under their name. \"Hand-written\" in the script means *no AI trailer*, which may be the human, a foreman session, or a squash that lost its trailers. In a repo the human says is 100% AI, read the two columns as *early era vs late era*, and treat any untagged net-deleting commits as a question (\"who is folding things back?\") not a fact.\n   When measuring surface area by hand, traps from the trials: `grep -v _test` filters *lines*, not files, so exported-name counts silently include `TestXxx` — filter the file list instead; and in zsh, `$REV:path` is always a parameter modifier (`:c`, `:l`, …), so quote every one: `\"$REV\":path`. A \"longest function\" measured as the gap between `fn` declarations will report an inline `mod tests` as a 2,800-line function — stop at `#[cfg(test)]`. And macOS's BWK awk does not support `\\s`: `^\\s*fn` silently anchors to column 0 and sees only top-level functions, which turned an `impl` block into a phantom 2,277-line function. Use `[[:space:]]` in awk and grep — or, per this repo's own rule, measure in Python. `git log --grep='\\bfix'` also matches \"fixture\" and \"fixed\"; the script's subject-only, word-bounded regex is the one to trust.\n2. **Read the flagged commits. Do not grade from the numbers.** For each zero-deletion fix and each fix-of-a-fix chain: `git show \u003Chash>`. Ask the tier-1 question — could the author say why? Is there a root cause named, or a guard around a symptom?\n3. **Measure the surface area.** `slop_surface.py \u003Crepo> --from \u003Cstart of window>` gives public names, function lengths and prod\u002Ftest split at both ends and the delta. Then read 2–3 of the changes behind the biggest movements and ask whether the growth bought leverage.\n4. **Check for a theory-holder.** Read `README`\u002F`CLAUDE.md`\u002F`DIARY.md` if present. Can the *repo* say why its modules exist? Does the architecture described match the architecture present?\n5. **Grade** (rubric below), then write the report.\n\n## Diff mode\n\nFor a branch or range: run `slop_diff.py --repo \u003Crepo> \u003Cbase>..\u003Chead> --require-thesis` first — it does the mechanical half and tells you whether the branch is already going back. Then, in this order, the judgement half — stop early if tier 1 fails badly:\n\n1. **Thesis.** Write the one sentence that accounts for the whole diff. If you can't — if it needs \"and also\" — that's the finding. Check it against the commit messages.\n2. **Surface-area delta.** Exported\u002Fpublic names, parameters, config\u002Fflags, special cases, files a reader must now open. Before vs after, as a short list. Did it grow? Did the growth buy anything?\n3. **Composability.** Does the new piece special-case existing ones, or compose with them? Would a second instance of this thing require touching callers?\n4. **Fix discipline.** If any commit calls itself a fix: what was deleted or changed, and is the root cause stated? A fix that only adds, with no cause named, is sent back — not failed, sent back with the question.\n5. **Reinvention.** For each new function or type, grep for an existing one that does the same job.\n6. **Smells** — annotate what you saw, clearly labelled as hints.\n7. **Reader test.** Could someone understand this diff without knowing what the prompt was?\n\n## `--explain` mode\n\nThe Explanation Gate, from the study that found requiring people to explain AI-generated changes before integrating them cut later maintenance failures roughly in half. Annoying by design; that's the point.\n\nAsk the user for a paragraph: what the change does and why, from memory, without re-reading the diff. Then compare it against the actual diff and report **what the diff does that the explanation didn't mention** — those are the parts of their own codebase they don't currently hold a theory of. No grade. Just the list, and how large it is relative to the change.\n\n## Grading\n\nGrade the *codebase or change*, not the tooling that produced it. Human-written slop exists; AI-written chosen code exists.\n\n- **A** — Every sampled change has one thesis that accounts for it. Surface area flat or shrinking over time. Fixes name causes and delete something. Refactoring is happening. A reader can reconstruct the author's reasoning from the code.\n- **B** — Mostly chosen. Occasional additive fix or unexplained growth, but the architecture still says why it exists.\n- **C** — Accreting. Fixes are guards. Surface area grows every change. Smells cluster. Someone still holds the theory, barely.\n- **D** — Sediment. Fix-of-a-fix chains. Add:delete ratio climbing, refactor share near zero. Nobody can say why half of it is there.\n- **F** — Dead in Naur's sense: modifiable, but not well. No theory-holder. Every change adds a layer.\n\n**A change with one clear thesis and a shrinking surface cannot grade below B, however large.** **A change with no statable thesis cannot grade above C, however small.**\n\n## Output\n\n```\n# Slop: \u003Crepo or change>   Grade: C\n\n**Thesis test:** \u003Cone line — pass\u002Ffail and why>\n**Surface area:** \u003Cgrew \u002F flat \u002F shrank — the concept count, before → after>\n**History (AI era vs hand era):** \u003Cthe two or three numbers that matter, from the script>\n\n## Chosen\n- \u003Cthings that were clearly decided, with hash\u002Ffile:line — say why they pass>\n\n## Unchosen\n- \u003Chash\u002Ffile:line> — \u003Cwhat it is> — \u003Cthe question the author couldn't answer>\n\n## Hints (smells — not graded)\n- \u003Cfile:line> — \u003Csmell>\n\n## What would make this pass\n- \u003Cconcrete, one line each>\n```\n\n## Rules\n\n- **Read the code. Never grade from the script's numbers alone** — they are proxies and the script says so.\n- **Name what was chosen, not just what wasn't.** A report that only lists faults teaches nothing about what good looks like here.\n- **Cite hashes and file:line** for everything in Chosen and Unchosen.\n- **Say what would make it pass**, concretely. \"Name the root cause in `fc2d871`\" beats \"improve fix discipline.\"\n- **Do not confuse your taste with the author's.** If the author states a reason you disagree with, that is chosen code you disagree with — a design conversation, not slop. Slop is code with no reason at all.\n- **Big ≠ bad. One impl ≠ bad. Small ≠ good.** If you catch yourself grading on volume, stop and re-read *What this skill does NOT penalise*.\n\n## Integration\n\n- **`\u002Fgo-team`** runs `slop_diff.py` in its gate (exit 2 = return to worker), reads `slop_surface.py --at HEAD` into its compass every ten cycles, and gives its consolidation seat the hotspot table as a work queue.\n- **`\u002Fscorecard`** row 14, *Accretion*, runs `\u002Fslop --quick` and reports its grade, the same way Security cross-checks `\u002Fdelegate-security-audit`.\n- **Dispatch rule for agents**, upstream of all of this: *before implementing, state the thesis in one sentence and what surface area it adds or removes.* Not \"make it small\" — \"make it chosen.\"\n","# Slop\n\nHand-written code was expensive, and the expense did invisible work: it forced planning, forced holding the design in your head, forced choosing the change that gave the most leverage for the least disruption, and forced writing for a reader. AI made lines free, and every discipline the cost was silently enforcing vanished with it.\n\nThe result is two kinds of code. **Hand-written code is the residue of understanding. Slop is the residue of attempts.** Every absence in hand-written code was a decision — no null check means \"I know this can't be null.\" Slop has no absences: every guard that *might* be needed is present, every fallback that *might* help is chained. It encodes uncertainty where good code encodes knowledge, and that is exactly why it's expensive to read — nothing was omitted, so a reader can't tell what matters.\n\n**Slop is unchosen code.** That is the whole test. The signals below detect the absence of choosing.\n\n## What this skill does NOT penalise\n\nGet this wrong and the skill becomes a lint for \"small,\" which is a different and worse thing.\n\n- **A big change is not slop.** A 500-line diff that collapses three renderers into one has a single sentence that accounts for all of it, and the codebase has *fewer* concepts afterward. That is excellent. Size is not the axis.\n- **A single-implementation abstraction is not slop.** A seam with one implementation is good when the interface is *smaller* than what it hides, it isolates a decision the author can *name*, and a second implementation would slot in without touching callers. Same shape on a diagram as \"make it configurable\"; opposite effect on the reader.\n- **A fix that only adds lines is not automatically slop.** Sometimes a case was genuinely missing. The tiebreaker is whether the root cause is stated.\n- **A high add:delete ratio driven by tests, docs and tooling is not slop.** Split additions into production code versus tests\u002Fdocs\u002Ftooling before reading the ratio as accretion — the history script does this. Five hundred lines of regression tests behind a ten-line fix is chosen; five hundred lines of guards is not. (First trial: a 7.5:1 ratio that looked like sediment turned out to be 86% tests and tooling; the production-code ratio was 1.97:1 in both the hand-written and AI eras — identical.)\n\n- **A high fix rate is not slop when fixing is the methodology.** A repo run through adversarial QA rounds (bug IDs like `QA-REG-218`, \"hunting round 48\") will be 30–40% fix commits by construction. The count says nothing; read *where* the fixes concentrate (the hotspot table) and whether each names its cause.\n- **A fix-of-a-fix chain in a hotspot file is not sediment until you've checked it's the same bug.** Three consecutive fixes to `Renderer.pm` on one day were three different bugs — every rendering bug lands in the file where rendering lives. That's a god-file finding (tier 2), not a fix-discipline finding (tier 3). Read the chain before naming it.\n\nIn every case the distinguishing question is the same: **could the author say why?** A change that can be explained, whose explanation accounts for the whole diff, is chosen. Grade intent, not volume.\n\n## The hierarchy — what decides the grade\n\n**1. Articulability (primary — decides).** Can the change be stated as one thesis, and does that thesis account for the whole diff? \"Collapse the three renderers into one\" — yes. \"Fix X, and also handle Y, and add a fallback for Z\" — that's three changes wearing one commit, none of them chosen. For a repo: can anyone say why each module exists?\n\n**2. Surface area and composability (measurable proxy — decides).** The *learning surface* is everything a reader or caller must know: exported names, function parameters, config options and flags, modes and special cases in behaviour, the number of files you must open to understand one thing. Count it before and after. Good changes — large or small — hold it flat or shrink it. Slop only ever grows it. Composability: can the pieces be combined without knowing about each other, or does each new piece special-case the last?\n\nThree surface-area shapes worth measuring directly, because the script can't see them:\n- **God files and god functions, and their trajectory.** Size the files the hotspot table names, at two or three points in history. A 5,000-line file absorbing 60 fixes and growing 20% a quarter is where sediment will form even if every individual commit is chosen. A 400-line function is a reader-load cost regardless of how it got there. But separate production lines from any inline test module first — a 5,000-line Rust file that is 60% `mod tests` is not the god file it looks like.\n- **The tracker itself.** `TODO.md` is part of the learning surface. One with hundreds of *done* items never pruned — thousands of lines a reader must wade through to find what's open — is theory-holder sediment. (`\u002Fscorecard`'s A1 dimension grades the same thing; cite it.)\n- **Docs versus code surface.** If the command palette grew 45% and `FEATURES.md` grew one line, either the new commands are variants of listed features or the doc is behind. Check which.\n\n**3. History trends (evidence — decides in repo mode).** These are the measured signatures of accretion, and `scripts\u002Fslop_history.py` computes them:\n- **Fix commits that delete nothing** — the single strongest signal. A fix that understands finds the wrong thing and removes it; a fix that doesn't wraps the symptom in a guard.\n- **Fix-of-a-fix chains** — the same file, two \"fix\" commits within two weeks.\n- **Churn** — code rewritten within two weeks of being written.\n- **Add:delete ratio** trending up; addition-only commits as a share.\n- **Refactor share** (moves\u002Frenames) trending to zero; **legacy code** never revisited — the codebase grows only at its edges.\n- **Big diff, trivial message** — \"fix typo\" touching 300 lines.\n\n**4. Code smells (weak priors — annotate only, never decide).** Things that are *usually* unchosen. They raise a flag for reading; they do not move the grade on their own:\n- Error-masking: broad `catch`\u002F`except`, swallowed errors, `|| default` chains, optional-chaining everywhere, retries around things that shouldn't fail.\n- Guards against states that cannot occur.\n- Abstractions that grow the surface: an interface bigger than what it wraps, mode flags, options with one caller, a factory that makes one thing, \"configurable\" things never configured.\n- Generic naming: `data`, `item`, `result`, `handle*`, `process*`, `utils`, `helper`, `manager`.\n- Narrating comments (`\u002F\u002F increment the counter`) versus load-bearing ones (`\u002F\u002F see #123: X must precede Y because …`).\n- Long methods, god classes, and the *modular mirage* — files split up but not semantically cohesive.\n- Tests that mirror the implementation, assert a mock was called, or would pass if the code were deleted.\n- New code that reinvents something already in the codebase instead of calling it.\n- **Copy-pasted tests.** Five near-identical test functions asserting the same string with different inputs, where one table-driven test would do. Tests aren't surface area, but repetition in them is still unchosen — and it's where AI output is most repetitive.\n- **Fleet artifacts** (repos run by autonomous agent crews): the same commit landing twice via two branches, tracker entries duplicated by merges and then de-duplicated in a later commit, derived data or build output committed then untracked. Each is small; together they measure how much of a reconciliation role the fleet needs. The script flags duplicate landings.\n\n## Modes\n\n```\n\u002Fslop                    # repo: history trends + a reading of recent flagged commits, graded\n\u002Fslop \u003Cbranch|range>     # diff: pre-merge audit of one change (go-team's gate uses this)\n\u002Fslop --explain          # the Explanation Gate: you explain the change; the skill shows what you missed\n\u002Fslop --quick            # one grade + three lines, for \u002Fscorecard's Accretion row\n```\n\n## The scripts\n\nThree, all Python, all approximate by construction and labelled so. `scripts\u002Fslop_lang.py` holds the per-language patterns (Go, Rust, Perl, Python, JS\u002FTS) the other two share.\n\n- **`slop_history.py \u003Crepo>`** — tier 3. Add:delete (production vs everything), fix commits that delete nothing, fix-of-a-fix chains, the fix-hotspot table, refactor moves, duplicate landings; split hand-written vs AI-attributed, or `--split YYYY-MM-DD`.\n- **`slop_surface.py \u003Crepo> --from REV [--to REV]`** — tier 2. Production LOC with inline test modules separated, public\u002Fexported names, function count, the longest functions, the biggest files, and the delta between two revisions. `--at REV` gives one reading (the compass uses this). This replaces every hand-measurement that went wrong in the first trials.\n- **`slop_diff.py --repo R \u003Cbase>..\u003Chead> [--require-thesis]`** — the pre-merge check, and `\u002Fgo-team`'s gate instrument. **Exit 0** clean (hints may print); **exit 2** *return to worker* with reasons: a fix that deletes no production line and names no `Cause:`; public surface that grows with no `Surface:` trailer; no `Thesis:` trailer (when required); a new function whose name nearly matches an existing one. Hints, never deciding: a subject that reads as several theses, added lines repeated three or more times, generic names. Returned is not failed — the worker answers the question and resubmits.\n\n## Repo mode\n\n1. **Run the script.** `python3 \u003Cskill-dir>\u002Fscripts\u002Fslop_history.py \u003Crepo>`. It splits history into a hand-written era and an AI-attributed era when it can (via `Co-Authored-By` trailers and similar markers) — that comparison, on the same codebase, is the most persuasive evidence there is. Use `--since` to narrow, `--split YYYY-MM-DD` if attribution is missing. Read the **production-code-only** ratio, not the headline one. Changelogs, docs and bug registries are excluded from fix signals automatically; check the exclusion line to make sure it caught the right files.\n   **Attribution is by trailer, not author.** In a repo worked by agents, every commit's author field is the human — agents commit under their name. \"Hand-written\" in the script means *no AI trailer*, which may be the human, a foreman session, or a squash that lost its trailers. In a repo the human says is 100% AI, read the two columns as *early era vs late era*, and treat any untagged net-deleting commits as a question (\"who is folding things back?\") not a fact.\n   When measuring surface area by hand, traps from the trials: `grep -v _test` filters *lines*, not files, so exported-name counts silently include `TestXxx` — filter the file list instead; and in zsh, `$REV:path` is always a parameter modifier (`:c`, `:l`, …), so quote every one: `\"$REV\":path`. A \"longest function\" measured as the gap between `fn` declarations will report an inline `mod tests` as a 2,800-line function — stop at `#[cfg(test)]`. And macOS's BWK awk does not support `\\s`: `^\\s*fn` silently anchors to column 0 and sees only top-level functions, which turned an `impl` block into a phantom 2,277-line function. Use `[[:space:]]` in awk and grep — or, per this repo's own rule, measure in Python. `git log --grep='\\bfix'` also matches \"fixture\" and \"fixed\"; the script's subject-only, word-bounded regex is the one to trust.\n2. **Read the flagged commits. Do not grade from the numbers.** For each zero-deletion fix and each fix-of-a-fix chain: `git show \u003Chash>`. Ask the tier-1 question — could the author say why? Is there a root cause named, or a guard around a symptom?\n3. **Measure the surface area.** `slop_surface.py \u003Crepo> --from \u003Cstart of window>` gives public names, function lengths and prod\u002Ftest split at both ends and the delta. Then read 2–3 of the changes behind the biggest movements and ask whether the growth bought leverage.\n4. **Check for a theory-holder.** Read `README`\u002F`CLAUDE.md`\u002F`DIARY.md` if present. Can the *repo* say why its modules exist? Does the architecture described match the architecture present?\n5. **Grade** (rubric below), then write the report.\n\n## Diff mode\n\nFor a branch or range: run `slop_diff.py --repo \u003Crepo> \u003Cbase>..\u003Chead> --require-thesis` first — it does the mechanical half and tells you whether the branch is already going back. Then, in this order, the judgement half — stop early if tier 1 fails badly:\n\n1. **Thesis.** Write the one sentence that accounts for the whole diff. If you can't — if it needs \"and also\" — that's the finding. Check it against the commit messages.\n2. **Surface-area delta.** Exported\u002Fpublic names, parameters, config\u002Fflags, special cases, files a reader must now open. Before vs after, as a short list. Did it grow? Did the growth buy anything?\n3. **Composability.** Does the new piece special-case existing ones, or compose with them? Would a second instance of this thing require touching callers?\n4. **Fix discipline.** If any commit calls itself a fix: what was deleted or changed, and is the root cause stated? A fix that only adds, with no cause named, is sent back — not failed, sent back with the question.\n5. **Reinvention.** For each new function or type, grep for an existing one that does the same job.\n6. **Smells** — annotate what you saw, clearly labelled as hints.\n7. **Reader test.** Could someone understand this diff without knowing what the prompt was?\n\n## `--explain` mode\n\nThe Explanation Gate, from the study that found requiring people to explain AI-generated changes before integrating them cut later maintenance failures roughly in half. Annoying by design; that's the point.\n\nAsk the user for a paragraph: what the change does and why, from memory, without re-reading the diff. Then compare it against the actual diff and report **what the diff does that the explanation didn't mention** — those are the parts of their own codebase they don't currently hold a theory of. No grade. Just the list, and how large it is relative to the change.\n\n## Grading\n\nGrade the *codebase or change*, not the tooling that produced it. Human-written slop exists; AI-written chosen code exists.\n\n- **A** — Every sampled change has one thesis that accounts for it. Surface area flat or shrinking over time. Fixes name causes and delete something. Refactoring is happening. A reader can reconstruct the author's reasoning from the code.\n- **B** — Mostly chosen. Occasional additive fix or unexplained growth, but the architecture still says why it exists.\n- **C** — Accreting. Fixes are guards. Surface area grows every change. Smells cluster. Someone still holds the theory, barely.\n- **D** — Sediment. Fix-of-a-fix chains. Add:delete ratio climbing, refactor share near zero. Nobody can say why half of it is there.\n- **F** — Dead in Naur's sense: modifiable, but not well. No theory-holder. Every change adds a layer.\n\n**A change with one clear thesis and a shrinking surface cannot grade below B, however large.** **A change with no statable thesis cannot grade above C, however small.**\n\n## Output\n\n```\n# Slop: \u003Crepo or change>   Grade: C\n\n**Thesis test:** \u003Cone line — pass\u002Ffail and why>\n**Surface area:** \u003Cgrew \u002F flat \u002F shrank — the concept count, before → after>\n**History (AI era vs hand era):** \u003Cthe two or three numbers that matter, from the script>\n\n## Chosen\n- \u003Cthings that were clearly decided, with hash\u002Ffile:line — say why they pass>\n\n## Unchosen\n- \u003Chash\u002Ffile:line> — \u003Cwhat it is> — \u003Cthe question the author couldn't answer>\n\n## Hints (smells — not graded)\n- \u003Cfile:line> — \u003Csmell>\n\n## What would make this pass\n- \u003Cconcrete, one line each>\n```\n\n## Rules\n\n- **Read the code. Never grade from the script's numbers alone** — they are proxies and the script says so.\n- **Name what was chosen, not just what wasn't.** A report that only lists faults teaches nothing about what good looks like here.\n- **Cite hashes and file:line** for everything in Chosen and Unchosen.\n- **Say what would make it pass**, concretely. \"Name the root cause in `fc2d871`\" beats \"improve fix discipline.\"\n- **Do not confuse your taste with the author's.** If the author states a reason you disagree with, that is chosen code you disagree with — a design conversation, not slop. Slop is code with no reason at all.\n- **Big ≠ bad. One impl ≠ bad. Small ≠ good.** If you catch yourself grading on volume, stop and re-read *What this skill does NOT penalise*.\n\n## Integration\n\n- **`\u002Fgo-team`** runs `slop_diff.py` in its gate (exit 2 = return to worker), reads `slop_surface.py --at HEAD` into its compass every ten cycles, and gives its consolidation seat the hotspot table as a work queue.\n- **`\u002Fscorecard`** row 14, *Accretion*, runs `\u002Fslop --quick` and reports its grade, the same way Security cross-checks `\u002Fdelegate-security-audit`.\n- **Dispatch rule for agents**, upstream of all of this: *before implementing, state the thesis in one sentence and what surface area it adds or removes.* Not \"make it small\" — \"make it chosen.\"\n",{"name":5,"description":7,"argument-hint":36},[37],"branch | rev-range | --explain | --quick","main","0d32bda2cb8e014372c2814f5aa47f48eee0f411","skills\u002Fslop","https:\u002F\u002Fgithub.com\u002Fjoewalnes\u002Fskills","https:\u002F\u002Fgithub.com\u002Fjoewalnes","Experimental Projects @ Stripe.\r\n\r\nPreviously: Apple, Google, ThoughtWorks, DRW, Startups.","2026-09-09 00:56:55",{"source":8,"skillName":5,"commands":46,"prompt":56,"zipAvailable":57},[47,50,53],{"tool":48,"command":49},"npx","npx skills add joewalnes\u002Fskills --skill slop",{"tool":51,"command":52},"bunx","bunx skills add joewalnes\u002Fskills --skill slop",{"tool":54,"command":55},"pnpm","pnpm dlx skills add joewalnes\u002Fskills --skill slop","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fjoewalnes\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fslop\u002FSKILL.md",true,[59,65,69,73],{"path":60,"resourceType":61,"resourceTypeDesc":62,"sizeBytes":63,"sourceHtmlUrl":64},"scripts\u002Fslop_diff.py","SCRIPT","脚本",5917,"https:\u002F\u002Fgithub.com\u002Fjoewalnes\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fslop\u002Fscripts\u002Fslop_diff.py",{"path":66,"resourceType":61,"resourceTypeDesc":62,"sizeBytes":67,"sourceHtmlUrl":68},"scripts\u002Fslop_history.py",13909,"https:\u002F\u002Fgithub.com\u002Fjoewalnes\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fslop\u002Fscripts\u002Fslop_history.py",{"path":70,"resourceType":61,"resourceTypeDesc":62,"sizeBytes":71,"sourceHtmlUrl":72},"scripts\u002Fslop_lang.py",2852,"https:\u002F\u002Fgithub.com\u002Fjoewalnes\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fslop\u002Fscripts\u002Fslop_lang.py",{"path":74,"resourceType":61,"resourceTypeDesc":62,"sizeBytes":75,"sourceHtmlUrl":76},"scripts\u002Fslop_surface.py",5584,"https:\u002F\u002Fgithub.com\u002Fjoewalnes\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fslop\u002Fscripts\u002Fslop_surface.py",[78,94,106,122,128,134],{"skillNo":79,"name":80,"nameZh":6,"description":81,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":82,"categories":83,"keywords":84,"publishedAt":31},"01M6K7MSG99DXYKTVVFGZWND1S","tool-web","Build a lightweight single-file web application with no external dependencies","https:\u002F\u002Fgithub.com\u002Fjoewalnes\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Ftool-web\u002FSKILL.md",[],[85,86,87,88,89,90,91,92,93],"tool web","tool","web","file","single-file","build","dependencies","application","with",{"skillNo":95,"name":96,"nameZh":6,"description":97,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":98,"categories":99,"keywords":100,"publishedAt":31},"01M6K7MPN2FG6M6JQFWFR18CJ0","todo","Add a new bug or todo to the project's tracker","https:\u002F\u002Fgithub.com\u002Fjoewalnes\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Ftodo\u002FSKILL.md",[],[96,101,102,103,104,105],"bug","tracker","task","project","add",{"skillNo":107,"name":108,"nameZh":6,"description":109,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":110,"categories":111,"keywords":112,"publishedAt":31},"01M6K7MCVREA4NZ46Q9JWZJ7TG","sitrep","Where were we? Branch, in-progress work, blocked agents, inbox, next steps. Use when resuming a session.","https:\u002F\u002Fgithub.com\u002Fjoewalnes\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fsitrep\u002FSKILL.md",[],[108,113,114,115,116,26,117,118,119,120,23,121],"next","read","progress","next steps","inbox","Bash","grep","work","session",{"skillNo":123,"name":124,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":125,"categories":126,"keywords":127,"publishedAt":31},"01M6K7M99FYMH9SFSEKB718J2B","scorecard","https:\u002F\u002Fgithub.com\u002Fjoewalnes\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fscorecard\u002FSKILL.md",[],[124],{"skillNo":129,"name":130,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":131,"categories":132,"keywords":133,"publishedAt":31},"01M6K7M4HNZR34GSB3V14KVCWA","retro","https:\u002F\u002Fgithub.com\u002Fjoewalnes\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fretro\u002FSKILL.md",[],[130],{"skillNo":135,"name":136,"nameZh":6,"description":137,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":138,"categories":139,"keywords":140,"publishedAt":31},"01M6K7M0QT6PD1SPE282ZQ0SM4","request","Ask another project's agents for a change instead of editing their repo. Use when a fix belongs in another repository.","https:\u002F\u002Fgithub.com\u002Fjoewalnes\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Frequest\u002FSKILL.md",[],[136,104,117,141,142,24,143,144,26,145,146,147,148,149],"repository","editing","ask","fix","show","done","id","for","change"]