skimmable
Skill17 starsChanged 4 months agoMITView on GitHub
Enforce code readability and state minimisation before opening or updating a pull request. Use when code is functionally complete and needs a final simplification pass focused on skimmability: reducing arguments, removing optionality and overrides, collapsing unnecessary abstractions, preferring discriminated unions, adding assertions at boundaries, handling variants exhaustively, deleting incidental changes, and making the diff shorter, clearer, and easier to review.
In this repository60 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- agent-browserSkill
- agent-engineeringSkill
- app-marketing-copySkill
- ascii-pixel-artSkill
- autopredictSkill
- autoresearchSkill
- babysit-prSkill
- bird-fastSkill
- blockchain-auditorSkill
- brainstormingSkill
- ceo-reviewSkill
- ck-reviewSkill
- cloudflare-managerSkill
- codex-advisorSkill
- content-trend-researcherSkill
- continuous-learningSkill
- coreml-optimizerSkill
- cto-reviewSkill
- direct-mail-strategistSkill
- evangelion-designSkill
- executing-plansSkill
- freshdesk-apiSkill
- gemini-image-generatorSkill
- gemini-visualSkill
- github-actions-templatesSkill
- googleSkill
- gsplat-optimizerSkill
- hyperagentSkill
- idea-mdSkill
- imagegenSkill
- ios-app-testerSkill
- llm-advisorSkill
- llm-evaluationSkill
- macos-appsSkill
- markdown-fetchSkill
- mcp-builderSkill
- mcp-testerSkill
- nano-bananaSkill
- opensea-apiSkill
- paperclipSkill
- playdate-devSkill
- poke-assistantSkill
- poplar-direct-mailSkill
- practical-typographySkill
- prompt-factorySkill
- qmdSkill
- scientific-critical-thinkingSkill
- security-best-practicesSkill
- security-threat-modelSkill
- seo-optimizerSkill
- shadertoySkill
- skill-finderSkill
- subway-infoSkill
- systematic-debuggingSkill
- tui-designerSkill
- ui-designSkill
- video-editorSkill
- writing-plansSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
30 rules. About 0 are common, 28 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈28
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 10
Prefer deleting code to explaining code.
- Distinctive: line 12
Keep the pass narrow: improve readability, state modelling, and diff clarity without changing product behaviour unless the current …
- Distinctive: line 21
Remove optional parameters unless they are truly required by callers.
- Distinctive: line 27
Prefer early returns over nested conditionals.
- Distinctive: line 28
Keep functions cohesive; do not split logic into many tiny wrappers.
- Distinctive: line 29
Avoid clever helpers, indirection, and generic abstractions.
- Distinctive: line 30
Remove overrides, escape hatches, and customisation points unless there is a proven need.
- Distinctive: line 31
Remove dead paths, temporary compatibility layers, and unrelated edits.
- Distinctive: line 40
Remove changes that do not help the main goal of the PR.
- Distinctive: line 49
If a simplification requires a separate behavioural decision, stop and call it out instead of smuggling it into the readability pass.
- Distinctive: line 61
Ask of every argument:
- Distinctive: line 93
After the boundary, write simple code that trusts the asserted shape.
- Distinctive: line 97
When code depends on a variant, make the variant explicit and handle all cases.
- Very specific: line 99
Prefer a switch on a discriminant.
- Distinctive: line 103
Do not silently ignore unknown values.
- Distinctive: line 109
Keep helper functions only when they:
- Distinctive: line 114
Do not split a 20-line readable function into five 4-line helpers just to look tidy.
- Distinctive: line 133
If a boolean changes behaviour, model the behaviour directly.
- Distinctive: line 149
Avoid repetitive checks like:
- Distinctive: line 158
If there is a default behaviour, encode it directly.
- Very specific: line 160
Do not add overrides like sortOrder = "desc", strategy = "auto", separator = ",", shouldLog = false unless callers truly need them.
- Distinctive: line 162
Every option multiplies states.
- Distinctive: line 166
Use these prompts during the pass:
- Distinctive: line 176
If a reviewer skims this in 30 seconds, will the intent be obvious?
- Distinctive: line 220
Prefer a smaller API. Add configurability only when a real caller needs it.
- Distinctive: line 382
Keep trivial logic close to use.
- Distinctive: line 386
Before opening or updating the PR, verify:
- Distinctive: line 399
If a choice is between clever and obvious, choose obvious.
- Distinctive: line 401
If a choice is between flexible and simple, choose simple.
- Distinctive: line 403
If a choice is between adding code and deleting code, prefer deleting code.
≈ “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.
Files
Skimmable
Review the change as if a tired reviewer must understand it in one fast pass.
Prefer deleting code to explaining code.
Keep the pass narrow: improve readability, state modelling, and diff clarity without changing product behaviour unless the current behaviour is obviously dead, redundant, or inconsistent with types.
Checklist
Apply these rules aggressively:
- Make the code obvious on first read.
- Reduce the number of states the code can represent.
- Reduce parameter count.
- Remove optional parameters unless they are truly required by callers.
- Replace boolean flags and loose option bags with discriminated unions when behaviour differs by mode.
- Handle every known variant exhaustively.
- Fail on unknown variants immediately.
- Trust static types inside the typed core; do not add defensive branches for impossible states.
- Assert at boundaries when loading data, parsing input, or reading external systems.
- Prefer early returns over nested conditionals.
- Keep functions cohesive; do not split logic into many tiny wrappers.
- Avoid clever helpers, indirection, and generic abstractions.
- Remove overrides, escape hatches, and customisation points unless there is a proven need.
- Remove dead paths, temporary compatibility layers, and unrelated edits.
- Bias toward fewer lines and fewer moving parts.
Working method
Follow this order:
1. Trim the diff
Remove changes that do not help the main goal of the PR.
Delete:
- incidental renames
- opportunistic refactors
- styling churn with no behavioural value
- compatibility code for callers that no longer exist
- unused helpers, types, branches, and comments
If a simplification requires a separate behavioural decision, stop and call it out instead of smuggling it into the readability pass.
2. Simplify data shape first
Reduce complexity in types before touching control flow.
Prefer:
- required fields over optional fields
- one obvious input shape over many flexible ones
- discriminated unions over booleans or loosely related fields
- named domain types over generic maps and stringly typed objects
Ask of every argument:
- Is it required?
- Can it be derived?
- Can two arguments become one domain object?
- Is it just an override for an API that is too flexible?
3. Simplify control flow
Make happy paths short and visible.
Prefer:
- early returns
- straight-line code
- one level of indentation where possible
- local branching near use
Avoid:
- nested
ifpyramids - defensive
elsebranches for impossible states try/catchfor expected values- hidden branching spread across helper functions
4. Make invalid states loud
Assert at boundaries.
Use assertions when:
- decoding external data
- reading files, env vars, or request payloads
- converting untyped data into typed domain values
- checking invariants that must hold
After the boundary, write simple code that trusts the asserted shape.
5. Exhaust variants
When code depends on a variant, make the variant explicit and handle all cases.
Prefer a switch on a discriminant.
End with an exhaustive check or assertion if the language allows it.
Do not silently ignore unknown values.
6. Collapse unnecessary abstraction
Inline small one-use wrappers when they hide the real logic.
Keep helper functions only when they:
- remove real duplication
- encode a domain concept
- make the caller meaningfully clearer
Do not split a 20-line readable function into five 4-line helpers just to look tidy.
Preferred patterns
Keep arguments few and strict
Bad signs:
- more than 3 parameters
- multiple booleans
- optional callback plus optional overrides plus optional config
- passing values already available on an object
Prefer:
- one required object when the fields belong together
- one discriminated union when there are modes
- separate functions when the behaviours are actually different
Prefer discriminated unions over booleans
If a boolean changes behaviour, model the behaviour directly.
Use:
kind: "draft" | "published"source: "cache" | "network"status: "idle" | "loading" | "success" | "error"
Avoid:
isDraftuseCacheisLoadingpluserrorplusdataon the same object unless the state machine truly permits all combinations
Prefer assertions over defensive code
At boundaries, assert once. Inside, trust the assertion.
Avoid repetitive checks like:
if (!user) returnif (!user.id) returnif (typeof user.id !== "string") return
when types and boundary validation already guarantee the shape.
Prefer one obvious path
If there is a default behaviour, encode it directly.
Do not add overrides like sortOrder = "desc", strategy = "auto", separator = ",", shouldLog = false unless callers truly need them.
Every option multiplies states.
Review prompts
Use these prompts during the pass:
- Can this function lose a parameter?
- Can this object lose an optional field?
- Can this branch become an early return?
- Can these two booleans become one union?
- Can this helper be inlined?
- Can this error path become an assertion at the boundary?
- Can this code fail loudly instead of guessing?
- Can this diff lose files or lines?
- If a reviewer skims this in 30 seconds, will the intent be obvious?
Examples
Reduce arguments and remove overrides
Before:
function createReport(
userId: string,
includeDrafts = false,
sortBy: "date" | "name" = "date",
sortDirection: "asc" | "desc" = "desc",
limit?: number,
overrides?: { timezone?: string; now?: Date }
) {
const now = overrides?.now ?? new Date()
const timezone = overrides?.timezone ?? "UTC"
return buildReport({
userId,
includeDrafts,
sortBy,
sortDirection,
limit,
now,
timezone,
})
}After:
type ReportScope =
| { kind: "published" }
| { kind: "all" }
function createReport(userId: string, scope: ReportScope) {
return buildReport({ userId, scope, now: new Date(), timezone: "UTC" })
}Prefer a smaller API. Add configurability only when a real caller needs it.
Replace booleans with a discriminated union
Before:
type SaveState = {
isSaving: boolean
error?: string
receipt?: string
}After:
type SaveState =
| { kind: "idle" }
| { kind: "saving" }
| { kind: "error"; message: string }
| { kind: "saved"; receipt: string }The second version prevents impossible combinations.
Handle variants exhaustively
Before:
function badgeColor(status: Status) {
if (status === "success") return "green"
if (status === "error") return "red"
return "gray"
}After:
function badgeColor(status: Status) {
switch (status) {
case "success":
return "green"
case "error":
return "red"
case "pending":
return "gray"
default:
return assertNever(status)
}
}Unknown variants should fail loudly during development.
Assert at the boundary, trust inside
Before:
async function loadAccount(accountId: string) {
const raw = await db.accounts.find(accountId)
if (!raw) {
throw new Error("Account not found")
}
if (typeof raw.email !== "string") {
throw new Error("Invalid account email")
}
return raw
}
function sendWelcomeEmail(account: any) {
if (!account) return
if (!account.email) return
mailer.send(account.email)
}After:
async function loadAccount(accountId: string): Promise<Account> {
const raw = await db.accounts.find(accountId)
assert(raw, "Account not found")
assert(typeof raw.email === "string", "Invalid account email")
return raw as Account
}
function sendWelcomeEmail(account: Account) {
mailer.send(account.email)
}Validate once. Keep the typed core simple.
Prefer early returns over nesting
Before:
function visibleItems(items: Item[], user?: User) {
if (user) {
if (user.isAdmin) {
return items
} else {
return items.filter((item) => !item.hidden)
}
} else {
return []
}
}After:
function visibleItems(items: Item[], user?: User) {
if (!user) return []
if (user.isAdmin) return items
return items.filter((item) => !item.hidden)
}Flatten the shape of the code.
Do not split logic into too many tiny functions
Before:
function checkout(cart: Cart) {
validateCart(cart)
const subtotal = calculateSubtotal(cart)
const tax = calculateTax(subtotal)
const total = calculateTotal(subtotal, tax)
return finalizeCheckout(total)
}
function calculateTotal(subtotal: number, tax: number) {
return subtotal + tax
}After:
function checkout(cart: Cart) {
assert(cart.items.length > 0, "Cart is empty")
const subtotal = sum(cart.items.map((item) => item.price))
const tax = subtotal * TAX_RATE
const total = subtotal + tax
return finalizeCheckout(total)
}Keep trivial logic close to use.
PR gate
Before opening or updating the PR, verify:
- The diff contains only necessary changes.
- Public APIs are stricter or simpler, not more configurable.
- Modes are modelled explicitly.
- Variants are handled exhaustively.
- Assertions exist at boundaries.
- The core logic trusts types instead of re-checking everything.
- Functions read top-to-bottom with minimal nesting.
- Argument counts are low.
- Helpers exist only when they clarify.
- The final version is shorter, plainer, and easier to skim.
If a choice is between clever and obvious, choose obvious.
If a choice is between flexible and simple, choose simple.
If a choice is between adding code and deleting code, prefer deleting code.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
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.

