addlightness
"Simplify, then add lightness." — Colin Chapman, Lotus. This skill owns the full
trim-and-benchmark loop: it measures code weight, removes fat without changing
behavior, verifies the change passes the equivalence gate (a change-magnitude/structural
signal, not a behavioral proof), and benchmarks the result. Lower weight
and a statistically significant speedup are the only success conditions.
The user's invocation carries the target file path(s) as trailing text (e.g.
/addlightness src/parser.js or "add lightness to lib/foo.py and lib/bar.py").
Read those paths from the request and treat them as the targets. If no path is
given, ask which file(s) to trim — do not guess.
Scope
- This skill (
/addlightness) owns the WHOLE pipeline: measure -> trim ->
verify -> benchmark. It both reports and edits.
/addlightness-review is READ-ONLY. If the user only wants a weight report
or a list of fat candidates with no edits, route there instead and stop.
/addlightness-bench is BENCHMARK-ONLY. If the user already has a before/after
pair and only wants the timing comparison, route there instead and stop.
When in doubt about whether the user wants edits, ask once. Default to the full
pipeline only when the request clearly asks to trim, slim, lighten, or speed up
the code.
Pipeline
Run these steps in order, per target file. Paths below use ${CLAUDE_PLUGIN_ROOT},
which Claude Code expands to this plugin's install directory.
Measure BEFORE. For each target file, capture baseline metrics. Either
delegate to the weight-analyst agent (spawn one weight-analyst invocation
per file and aggregate the JSON yourself — the agent analyzes one file per
run) or run the engine directly:
node "${CLAUDE_PLUGIN_ROOT}/lib/weigh.js" <file> --json
With --json this emits one JSON object with loc, cyclomatic, imports,
functions, nesting, weight, a tokens proxy, and an approx boolean
(true = JS/TS regex approximation, false = Python ast-accurate). Parse that
line; without --json the engine prints a human-readable table, not JSON.
Record the full component set, not just the scalar weight — the report table
needs every dimension.
Establish a green baseline. Ask the user to confirm the file's tests pass
right now (or run them if you know the command). If there is no test coverage,
say so explicitly and recommend adding characterization tests before trimming.
Static equivalence checks are change-magnitude signals, not behavioral proof —
the user's own test suite is the only true runtime-equivalence guarantee.
Trim. Spawn the code-trimmer agent for the file, passing the BEFORE
metrics and the trust-boundary rule (below). One file per trimmer invocation;
the trimmer hard-refuses 3+ files of unrelated scope in a single pass.
Verify equivalence. After the trimmer edits a file, compare the saved
original against the trimmed version:
node "${CLAUDE_PLUGIN_ROOT}/lib/equivalence.js" <before> <after>
The gate writes a JSON object whose equivalent field is the verdict, then
exits 0 on a pass. Proceed only when that field is identical,
modulo-renames, or signature-match. Treat unknown (the zero-dep gate
could not parse the file) and body-changed (signatures + behavior-leaves
match but the body structure changed — a soft signal, no auto-revert) as
inconclusive — do not auto-revert, but make the "run your tests" reminder
mandatory and emphasized (body-changed is louder than unknown). REVERT the edit and
report it when the process exits non-zero, prints the literal regressed.
sentinel, or the equivalent field is DIFFERENT — never ship a trim that
fails the gate.
Measure AFTER. Re-run weigh.js on the trimmed file to capture the new
metrics:
node "${CLAUDE_PLUGIN_ROOT}/lib/weigh.js" <file> --json
Benchmark (when runnable). If the file (or a target that exercises it) can
be run as a command, benchmark before vs after:
"${CLAUDE_PLUGIN_ROOT}/scripts/benchmark.sh" \
--runs 10 --warmup 3 \
--before '<before-command>' \
--after '<after-command>'
The harness takes flags only (it dies on positional args), uses hyperfine if
present else a date+awk fallback, and prints a JSON line with before_ms,
after_ms, pct_change (negative = after faster), welch_t, and
significant_at_95. If there is no sensible runtime
target, skip benchmarking and report a weight-only result — do not fabricate a
speedup.
Trust-boundary rule (load-bearing — apply on every defensive-check removal)
KEEP defensive checks on externally-controlled inputs. Externally-controlled
means public API parameters, file/network/process IO, parsed data, environment
variables, and anything derived from user input. These validations stay, always.
Only remove checks on internally-produced or type-guaranteed values — where the
type system or local control flow already proves the value cannot be the thing the
check guards against.
Never strip input validation. This is the #1 regression vector: tests pass with
well-formed inputs even after a guard is wrongly removed, so the breakage only
surfaces in production with hostile or malformed input.
Three-pass trim order
The trimmer works in this fixed order so judgment effort is never spent on lines
that a cheaper pass would have deleted anyway.
- Mechanical (zero-judgment, lint-autofixable): remove unused imports / vars /
exports, no-else-return, useless catch / return / rename / constructor,
redundant boolean compares and coercions.
- Semantic (judgment): inline single-use wrappers, collapse redundant control
flow, drop ONLY proven-impossible defensive checks (per the trust-boundary
rule), remove redundant destructure / coercion.
- Style (cosmetic): shorten identifiers in narrow / private scope only, delete
what-restating comments, keep why-comments.
JS traps the trimmer honors and you must not override: keep return await inside
try/catch; don't strip async without checking call sites (it changes the return
type and turns sync throws into rejected Promises); don't blanket-delete empty
catch blocks (intentional swallow vs bug is ambiguous).
Report format
Present a before/after table per file, then the verdict.
| Metric |
Before |
After |
Delta |
| LOC |
… |
… |
… |
| Cyclomatic |
… |
… |
… |
| Imports |
… |
… |
… |
| Functions |
… |
… |
… |
| Nesting |
… |
… |
… |
| Weight |
… |
… |
… |
- Weight reduction:
(before_weight - after_weight) / before_weight * 100%.
- Benchmark: % speedup with a significance flag. Gate on the harness's
emitted
significant_at_95 bool (true only when the Welch |t| exceeds a
df-aware two-tailed 95% Welch critical value, emitted as t_crit_95, ~2.1-2.3
at the default N=10); never recompute against a fixed 1.96. Label anything else
"not statistically significant" and do not claim it as a win.
- Edit list: each change tagged
mechanical | semantic | style with a
one-line justification.
- KEEP list (co-equal): what was deliberately preserved and why — especially
every defensive check kept under the trust-boundary rule.
Weight is a RELATIVE before/after metric (lower = lighter), not an absolute
industry standard. Present it as a comparison, never as a grade.
What NOT to do
- Don't strip validation or defensive checks on externally-controlled inputs.
- Don't change public signatures, exports, thrown-error types, or async contracts.
- Don't claim a speedup that isn't statistically significant.
- Don't refactor files with no test coverage without first recommending (and
ideally adding) characterization tests.
- Don't edit 3+ files of unrelated scope in one pass — split the work.
- Don't ship a trim that failed the equivalence gate; revert and report it.
- Don't fabricate a benchmark when there's no runnable target — report weight only.
1---2name: addlightness3description: Simplify, then add lightness. Analyzes one or more source files for AI-generated 'code fat', removes it while preserving behavior, verifies the change passes the equivalence gate (a structural signal, not a behavioral proof), then benchmarks the speedup. Multi-pass: measure -> trim -> verify -> benchmark. Use when the user says "add lightness", "trim this code", "remove the fat", "slim down", "make this leaner/faster", "simplify and benchmark", or invokes /addlightness. Also auto-triggers when the user wants sloppy first-pass AI code made trim and fast. Applies edits; for a read-only weight report with no changes use /addlightness-review.4---56# addlightness78"Simplify, then add lightness." — Colin Chapman, Lotus. This skill owns the full9trim-and-benchmark loop: it measures code weight, removes fat without changing10behavior, verifies the change passes the equivalence gate (a change-magnitude/structural11signal, not a behavioral proof), and benchmarks the result. Lower weight12and a statistically significant speedup are the only success conditions.1314The user's invocation carries the target file path(s) as trailing text (e.g.15`/addlightness src/parser.js` or "add lightness to lib/foo.py and lib/bar.py").16Read those paths from the request and treat them as the targets. If no path is17given, ask which file(s) to trim — do not guess.1819## Scope2021- **This skill (`/addlightness`)** owns the WHOLE pipeline: measure -> trim ->22 verify -> benchmark. It both reports and edits.23- **`/addlightness-review`** is READ-ONLY. If the user only wants a weight report24 or a list of fat candidates with no edits, route there instead and stop.25- **`/addlightness-bench`** is BENCHMARK-ONLY. If the user already has a before/after26 pair and only wants the timing comparison, route there instead and stop.2728When in doubt about whether the user wants edits, ask once. Default to the full29pipeline only when the request clearly asks to trim, slim, lighten, or speed up30the code.3132## Pipeline3334Run these steps in order, per target file. Paths below use `${CLAUDE_PLUGIN_ROOT}`,35which Claude Code expands to this plugin's install directory.36371. **Measure BEFORE.** For each target file, capture baseline metrics. Either38 delegate to the `weight-analyst` agent (spawn one weight-analyst invocation39 per file and aggregate the JSON yourself — the agent analyzes one file per40 run) or run the engine directly:4142 ```bash43 node "${CLAUDE_PLUGIN_ROOT}/lib/weigh.js" <file> --json44 ```4546 With `--json` this emits one JSON object with `loc`, `cyclomatic`, `imports`,47 `functions`, `nesting`, `weight`, a `tokens` proxy, and an `approx` boolean48 (true = JS/TS regex approximation, false = Python ast-accurate). Parse that49 line; without `--json` the engine prints a human-readable table, not JSON.50 Record the full component set, not just the scalar weight — the report table51 needs every dimension.52532. **Establish a green baseline.** Ask the user to confirm the file's tests pass54 right now (or run them if you know the command). If there is no test coverage,55 say so explicitly and recommend adding characterization tests before trimming.56 Static equivalence checks are change-magnitude signals, not behavioral proof —57 the user's own test suite is the only true runtime-equivalence guarantee.58593. **Trim.** Spawn the `code-trimmer` agent for the file, passing the BEFORE60 metrics and the trust-boundary rule (below). One file per trimmer invocation;61 the trimmer hard-refuses 3+ files of unrelated scope in a single pass.62634. **Verify equivalence.** After the trimmer edits a file, compare the saved64 original against the trimmed version:6566 ```bash67 node "${CLAUDE_PLUGIN_ROOT}/lib/equivalence.js" <before> <after>68 ```6970 The gate writes a JSON object whose `equivalent` field is the verdict, then71 exits 0 on a pass. Proceed only when that field is `identical`,72 `modulo-renames`, or `signature-match`. Treat `unknown` (the zero-dep gate73 could not parse the file) and `body-changed` (signatures + behavior-leaves74 match but the body structure changed — a soft signal, no auto-revert) as75 inconclusive — do not auto-revert, but make the "run your tests" reminder76 mandatory and emphasized (`body-changed` is louder than `unknown`). **REVERT the edit and77 report it** when the process exits non-zero, prints the literal `regressed.`78 sentinel, or the `equivalent` field is `DIFFERENT` — never ship a trim that79 fails the gate.80815. **Measure AFTER.** Re-run `weigh.js` on the trimmed file to capture the new82 metrics:8384 ```bash85 node "${CLAUDE_PLUGIN_ROOT}/lib/weigh.js" <file> --json86 ```87886. **Benchmark (when runnable).** If the file (or a target that exercises it) can89 be run as a command, benchmark before vs after:9091 ```bash92 "${CLAUDE_PLUGIN_ROOT}/scripts/benchmark.sh" \93 --runs 10 --warmup 3 \94 --before '<before-command>' \95 --after '<after-command>'96 ```9798 The harness takes flags only (it dies on positional args), uses hyperfine if99 present else a date+awk fallback, and prints a JSON line with `before_ms`,100 `after_ms`, `pct_change` (negative = after faster), `welch_t`, and101 `significant_at_95`. If there is no sensible runtime102 target, skip benchmarking and report a weight-only result — do not fabricate a103 speedup.104105## Trust-boundary rule (load-bearing — apply on every defensive-check removal)106107**KEEP defensive checks on externally-controlled inputs.** Externally-controlled108means public API parameters, file/network/process IO, parsed data, environment109variables, and anything derived from user input. These validations stay, always.110111**Only remove checks on internally-produced or type-guaranteed values** — where the112type system or local control flow already proves the value cannot be the thing the113check guards against.114115Never strip input validation. This is the #1 regression vector: tests pass with116well-formed inputs even after a guard is wrongly removed, so the breakage only117surfaces in production with hostile or malformed input.118119## Three-pass trim order120121The trimmer works in this fixed order so judgment effort is never spent on lines122that a cheaper pass would have deleted anyway.1231241. **Mechanical** (zero-judgment, lint-autofixable): remove unused imports / vars /125 exports, no-else-return, useless catch / return / rename / constructor,126 redundant boolean compares and coercions.1272. **Semantic** (judgment): inline single-use wrappers, collapse redundant control128 flow, drop ONLY proven-impossible defensive checks (per the trust-boundary129 rule), remove redundant destructure / coercion.1303. **Style** (cosmetic): shorten identifiers in narrow / private scope only, delete131 what-restating comments, **keep why-comments**.132133JS traps the trimmer honors and you must not override: keep `return await` inside134try/catch; don't strip `async` without checking call sites (it changes the return135type and turns sync throws into rejected Promises); don't blanket-delete empty136catch blocks (intentional swallow vs bug is ambiguous).137138## Report format139140Present a before/after table per file, then the verdict.141142| Metric | Before | After | Delta |143| ----------------- | ------ | ----- | ----- |144| LOC | … | … | … |145| Cyclomatic | … | … | … |146| Imports | … | … | … |147| Functions | … | … | … |148| Nesting | … | … | … |149| **Weight** | … | … | … |150151- **Weight reduction:** `(before_weight - after_weight) / before_weight * 100`%.152- **Benchmark:** % speedup with a significance flag. Gate on the harness's153 emitted `significant_at_95` bool (true only when the Welch `|t|` exceeds a154 df-aware two-tailed 95% Welch critical value, emitted as `t_crit_95`, ~2.1-2.3155 at the default N=10); never recompute against a fixed 1.96. Label anything else156 "not statistically significant" and do not claim it as a win.157- **Edit list:** each change tagged `mechanical` | `semantic` | `style` with a158 one-line justification.159- **KEEP list (co-equal):** what was deliberately preserved and why — especially160 every defensive check kept under the trust-boundary rule.161162Weight is a RELATIVE before/after metric (lower = lighter), not an absolute163industry standard. Present it as a comparison, never as a grade.164165## What NOT to do166167- Don't strip validation or defensive checks on externally-controlled inputs.168- Don't change public signatures, exports, thrown-error types, or async contracts.169- Don't claim a speedup that isn't statistically significant.170- Don't refactor files with no test coverage without first recommending (and171 ideally adding) characterization tests.172- Don't edit 3+ files of unrelated scope in one pass — split the work.173- Don't ship a trim that failed the equivalence gate; revert and report it.174- Don't fabricate a benchmark when there's no runnable target — report weight only.