| name | strict-simplify |
| description | Use when reviewing code to replace redundant or verbose logic with a provably-equivalent simpler form — custom code that duplicates a stdlib/builtin or an existing project function, dead/no-op arguments, collapsible redundant expressions, duplicate inline logic that reimplements something already defined in the codebase. Triggers on "strict simplify", "/strict-simplify", "reduce redundant code". Does not restructure, rename, reformat, optimize, or fix bugs. |
Strict Simplify
Overview
Replace code only when the replacement is provably identical in behavior and the
equivalence is clear from reading the diff. The output is a git diff a human can
approve line-by-line without running the code to trust it.
This skill does less than simplify on purpose. It does not restructure, rename,
reformat, optimize, or fix bugs. Narrowness is the feature.
The Equivalence Gate
A change is allowed only if it passes ALL six checks. Otherwise: skip it.
- Identical behavior for every input, including edge cases and error paths.
- Clear by reading the diff — equivalence is clear from reading the diff. No execution.
Documented language/standard-library semantics count as "reading" (you may rely on what
sum, includes, or a default argument is specified to do); assumptions about your
own untested code paths do not.
- No signature / type / API change — nothing observable to callers changes.
- No change to side effects, evaluation order, or error/exception behavior.
- Local — not a cross-function move. Inlining a single-use variable into the very next
line counts as local.
- When in doubt, skip. Bias is always toward leaving code alone.
Violating the letter of these is violating the spirit. "Basically the same" that fails any
one check is not a candidate. If you cannot write a clear "why equivalent"
justification, it is not a candidate.
In-Scope Categories
- Custom → stdlib/builtin — hand-rolled logic replaced by an exact standard-library
equivalent (manual sum loop →
sum()).
- Dead / no-op values & args — remove arguments/values with no effect
(
from("", "", "Zord") → from("Zord"), when a matching signature exists).
- Redundant logic collapse —
if x { true } else { false } → x; double negation; a
variable assigned once and used once on the next line.
- Verbose → idiomatic equivalent — a verbose construct → a shorter one doing exactly
the same thing (manual transform loop →
map/comprehension).
- Duplicate inline logic → existing project function — inline code that reimplements
logic already defined elsewhere in the codebase, OR multiple call sites that each
reimplement the same operation instead of calling the one function that already does it.
Replace the inline copy with a call to the existing function.
- The existing function must already exist — do not create one.
- Its behavior must provably match for every input the call site handles.
- If two project functions do the same thing with slight discrepancies, pick the one
whose behavior is correct for the call site and route all call sites to it. Do not
merge the functions themselves — that is restructuring.
These name the common shapes; they are not a closed list. Be ambitious about discovery
— real codebases hold redundancies these four never named. Ambition applies to what you
look for, never to how sure you must be: every self-found candidate faces the same six
checks.
Hard Out-of-Scope (forbidden)
- No comment removal or editing.
- No renaming (variables, functions, types, files).
- No reordering or restructuring of functions/blocks.
- No performance/efficiency changes (even if "obviously faster").
- No bug fixes — if you find a bug, report it, do not fix it.
- No new abstractions, helpers, or layers — but replacing inline logic with an existing project function is in scope (category 5).
- No dead-code removal (unused variables, imports, functions) — that is a separate concern.
- No formatting-only or whitespace-only changes.
- No changes that alter logs, errors, or serialized output.
Process
- Preflight — run
git status. If the working tree is not clean, STOP and ask the
user to commit or stash first, so the simplification diff stays isolated.
- Target — whole repo by default; if the user passed a path, restrict to it.
- Discover — read the code and build a candidate ledger. Each row:
file:line · category · current → proposed · why-equivalent.
Drop every row that fails the gate.
- Apply — apply all surviving candidates. Leave edits unstaged.
- Report — show
git diff + the ledger, plus a short
"found but skipped — not provably equivalent" list so nothing is silently dropped.
If you found a bug, report it here too — do not fix it.
For very large repos you MAY delegate discovery to cavecrew subagents. Optional, not required.
Examples — acceptable only when the inline condition holds
These are illustrative, not exhaustive. The gate applies to any redundancy you find, not
just these shapes.
Each example is a candidate, not a guarantee. The // SKIP if … and // only if … notes are
gates, not footnotes: if you cannot confirm the condition by reading, the change is not
acceptable — skip it.
Custom → stdlib/builtin
total = 0
for n in nums: total += n
total = sum(nums)
biggest = items[0]
for x in items[1:]:
if x > biggest: biggest = x
biggest = max(items)
let found = false;
for (const x of arr) if (x === target) { found = true; break; }
const found = arr.includes(target);
out = ""
for i, part in enumerate(parts):
out += part
if i < len(parts) - 1: out += ", "
out = ", ".join(parts)
Dead / no-op values & args
directories::from("", "", "Zord")
json.dumps(data, indent=None) // → json.dumps(data) // None is the documented default
const url = "" + base + "/" + path;
const url = base + "/" + path;
fn log_it(x: i32) { println!("{x}"); return; }
fn log_it(x: i32) { println!("{x}"); }
Redundant logic collapse
if x > 0 { return true } else { return false }
result = compute(x)
return result
if (!(!isReady)) { ... }
Verbose → idiomatic equivalent
out = []
for x in xs:
if x > 0: out.append(x)
out = [x for x in xs if x > 0]
const name = user && user.profile ? user.profile.name : undefined;
const name = user?.profile?.name;
Duplicate inline logic → existing project function
stem = Path(filename).stem.lower()
for room, keywords in ROOM_KEYWORDS.items():
if any(k in stem for k in keywords):
return room
return "general"
return infer_room(filename)
Counter-Examples — SKIP these (look simpler, fail the gate)
| Tempting change | Why skip |
|---|
| Reorder/regroup for cleanliness | Restructuring, not simplification; risks init/side-effect order |
| "Faster" rewrite (bitwise trick, swap data structure) | Performance is out of scope; equivalence not readable |
Drop a guard that looks redundant (if items: before a loop) | May protect a downstream assumption; changes empty-input behavior |
Inline a call across a side effect (f() that logs/mutates) | Equivalent only if f is visibly pure |
| Delete stale comment / collapse blank lines / reflow | Forbidden; not a logic change |
cond ? cond : fallback → cond || fallback on a value | Differs on 0, "", NaN — only safe when cond is boolean |
flag == True → bool(flag) or if flag: when type unknown | is_ok(2): 2 == True is False but bool(2) is True — differs unless flag is provably bool |
user && user.x → user?.x when user may be 0/"" | ?. guards nullish only, && guards falsiness |
Rename tmp → userCount | Renaming is out of scope |
| Fix a bug you noticed | Report it separately; do not fix in this pass |
| Two functions differ slightly — merge them into one | Merging/restructuring functions is out of scope; only route call sites |
| Existing function handles a superset of inputs — assume it's safe | Verify the extra input handling doesn't change behavior at this call site |
Red Flags — STOP, you are over-reaching
- You're editing a comment, blank line, or whitespace.
- You're renaming or moving something.
- You're about to write "this is basically the same" instead of a clean equivalence line.
- You're "improving" performance.
- You're fixing a bug.
- You're relying on assumptions rather than what you can read — that means skip, not "probably fine".