Skip to content
cccskills
FreePublished on GitHub

reduce-complexity

Measure whether a change made the tree simpler, on numbers rather than impressions — line counts, branching, coupling, interface width, rule count, standing exemptions and model-visible prose — across one diff or a whole stack of pull requests. Use before claiming a pass reduced complexity, when deciding which pull request in the stack added the machinery, and to read a function's branch count, which no v2 gate reports.

The English summary is being prepared. Showing the original description.

See how to install

Files included (4)

  • SKILL.md9.0 KB
  • scripts/measure.py17.9 KB
  • scripts/scope.sh5.0 KB
  • scripts/stack-complexity.py20.1 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

Reduce complexity

simplify (/simplify) is the method: read the callers, fold into the owner, delete before you add. This skill is the instrument. It answers one question — did that actually make the tree smaller, or only move the mass — and it answers it the same way twice, so two passes are comparable.

The honest order is: measure, cut, measure again, and put both numbers in the PR body. A simplification that cannot show a number it moved is a rewrite.

These numbers are one side of a trade. Rule 13 of AGENTS.md maps every concept as owner → live reader → decision it changes → evidence → hostile test and drops it when a link is missing; this skill measures what the concept costs, never the decision it changes. A pass that reports a large fall here and nothing about what the component still decides has shown that it is smaller, not that it is better.

All three scripts are v1's, adapted; v1's copies read back with git show 5bc9988:.claude/skills/reduce-complexity/scripts/<name>, and no other copy runs. They are Python and shell where the rest of .claude is bun TypeScript, because a port keeps that transfer and a rewrite would not.

The whole stack, on seventeen measures

python3 .claude/skills/reduce-complexity/scripts/stack-complexity.py origin/main HEAD
python3 .claude/skills/reduce-complexity/scripts/stack-complexity.py origin/main '#<bottom>' '#<top>'
python3 .claude/skills/reduce-complexity/scripts/stack-complexity.py --repo /abs/worktree --per-file origin/main HEAD

It reads every revision through git plumbing, so it needs no worktree, touches nothing and runs anywhere in the repository. A #<n> argument is a pull request number in the repository this checkout's origin names, resolved through gh and fetched if this checkout has not seen it.

groupmeasureswhat a rise means
how much is theresource files, nonblank source lines, nonblank test linesmore to read. Test lines rising while source holds usually means a mechanism got proved; source rising while tests hold usually means it did not
how much branchingdecision points, decisions per 100 linesmore paths per function. Both are proxies. v1 read exact branching debt off a cyclomatic baseline; v2 has no complexity gate (AGENTS.md §12.10) and so no baseline, and the density is the second reading: a stack that added lines and branches together held it
how tangledimport edges, mean fan-out, hub files, max fan-inmore places one edit reaches. An edge is a relative import or a #src/, #tools/ or #skills/ one, resolved through package.json's imports; v2 writes about a third of its internal imports that way. A hub is a file at or above its revision's 90th fan-out percentile
how wide the interfaceexported symbols, optional fields, signatures with 5+ parametersmore states every reader must handle. Optional fields are the quiet one: each ?: is a case somebody downstream has to consider
how many rulesdistinct refusal codes, environment knobsa longer contract to satisfy, and more ways to be refused
how much is excusedwaived findings, copied-file ceilingstools/oxlint/not-slop.tsv rows, a lint site answered rather than changed, and copiedFileLimits in tools/loc/source-policy.json. A waiver falls when its site changes until the finding stops firing; §12.10 keeps the ceiling map empty, so anything above 0 there is a finding by itself
how much a model readsprompt literal bytes, and the same per composermore prose asked of an agent per turn. This is the group the others are usually traded against

"Source" is what tools/loc/source-policy.ts calls authored: src, tools and packages, never vendor. The composers are named explicitly in the script, by one rule — a file is listed when it builds prompt text or declares a tool description — because an AST census guesses audiences and a delta should be exact. A new composer goes in that list in the same pull request.

The first revision is read as first...last, the point they diverged, so work landed on main after the branch was cut is not charged to the branch. Getting this wrong is the standard error: in v1 a six-PR stack once appeared to have deleted 2,872 test lines it had not touched. --literal-base compares the tips as given when that is what you want. Run git fetch origin first and name origin/main, not main: a local main that has not been updated is an ancestor of the branch, so nothing warns you, and the branch is credited with everything main has landed since.

Comparing pull requests

Name the stack bottom-to-top and every PR gets a column, so you can see which one moved a measure instead of only that the stack did. Over #164 and #172 of s-smits/anabasis-v2, where v2 was built before it moved to this repository, from the commit below them:

measure                        c97d945        #164        #172         net
nonblank source lines           43,159      43,169      43,204         +45    +0.1%
prompt literal bytes            71,924      71,924      72,408        +484    +0.7%
     +484  9,751 -> 9,751 -> 10,235  src/builder/prompt.ts

#164 moved ten source lines and no model-visible byte; #172's whole prose cost was 484 bytes in one composer. A single base-to-tip delta would have said only that the pair was 484 bytes heavier.

For two branches that are not in one line — siblings, or a rewrite against the thing it replaces — compare each against their common base and read the two nets. Do not compare sibling tips directly: each carries the other's absence as a deletion.

One diff, and a function's branch count

.claude/skills/reduce-complexity/scripts/scope.sh [<PR#>|<commit>|<a..b>|<paths>] -C <worktree> -o <scope.diff>
.claude/skills/reduce-complexity/scripts/measure.py --diff <scope.diff> --base <pre-change ref> -C <worktree>

scope.sh resolves the base: the PR's parent on a stack, never main by default. measure.py prints functions by branch count and length, exports by caller count (UNUSED, one-caller), the functions over a ceiling, then two sections:

  • budget: production and test lines net, new and deleted files, new production functions net of moved ones, and the names each import source gained. Point --base at the head before the change you are simplifying, not the PR base, when the question is what a repair costs.
  • repeats: added code that already exists elsewhere in tracked source — the "already in this codebase?" rung answered for you. Call that owner, then delete the other local copies too.

It reads branch counts from node_modules/oxlint/bin/oxlint with complexity, max-lines-per-function and max-lines set to a maximum of 0 in a temporary config of its own, so every function is reported. That is a measurement, not a change to this repository's lint configuration, and it is the only cyclomatic reading v2 has. The line ceilings default to source-policy.ts's 115 and 800. --complexity defaults to v1's 21, which nothing in v2 enforces, so a function over it is a lead and not a refusal. Its line counts skip comments and source-policy.ts's do not, so a function near 115 here may already be over there.

Run it once before editing and once after, and put the budget lines in the report. The worktree must hold the after-state.

Reading prose as complexity

Model-visible text is the measure most often left out, and in this system it is the one that decides behaviour. Sort every model-visible sentence into three kinds:

  • Frame — what the agent is for, and what it may not do. Irreducible; keep it.
  • Fact — something the agent cannot observe, told to it in words. It belongs in a returned value. A fact in a prompt is read once, compacted away and never checked.
  • Hope — a property we want the answer to have, asked for. It belongs in a refusal or a computed result. A hope in a prompt is a probability; the same property enforced by the harness is a guarantee.

Cutting a Hope is only honest once the mechanism that replaces it exists. The trade that buys — prompt bytes down, source lines up — is why the last group is read against the others rather than on its own. The reverse trade is the one to catch: a clause added to a prompt that nothing reads. When a prompt gains a clause, name its reader.

What a pass must not cut

The rules of AGENTS.md §8 are what no pass trades. A measure that improved because one of them left — a wall that stopped holding, a non-result that became a fail, a check that stopped reading the field's own tool — is not a simplification, whatever the numbers say.

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

Use after an Anabasis v2 comparison, checkpoint or system change, and before any sentence claims that a harness, a model or a patch improved something. States what one reading may be said to show: the identities it was made under, the counts kept apart, whether it was repeated, which part of a harness it belongs to, whether a mechanism was live in the run, and whether the measurement is valid as distinct from whether it was exploited. Ends in one fixed report.

The English summary is being prepared. Showing the original description.

s-smits/anabasis63Updated Oct 19, 2026

Launch and collect independent Codex sessions (gpt-6-luna at high, xhigh or max; gpt-6.1-sol at low to xhigh) for bounded parallel work, from Claude Code or from Codex: one manifest, one detached launcher, one report a session, a drain while it runs, and a retry of the sessions that ended without a report. Owns the Codex transport when another skill sets the questions, as whole-run-investigation does for its lanes. Use when the operator asks for Luna or Sol sessions, a swarm, many sessions, a reasoning effort, a Codex subagent from Claude Code, or a later collection of reports. Tell a request to launch from one to wait and collect.

The English summary is being prepared. Showing the original description.

s-smits/anabasis63Updated Oct 19, 2026

The commit-R protocol: a test-driven rewrite of one compartment of Anabasis v2. Commit what is in flight, remove the compartment's tests in an "R:" commit, write them again from a stated hypothesis so the production code fails on purpose, remove the production files in a second "R:" commit, then write the production code again, rewrite the neighbouring functions the old shape bent, and delete what served only it. Use when the operator says "commit R", "commit-R protocol", "remove and rewrite the tests" or "rewrite from scratch", or asks for a test-first pass that looks for a faster, simpler path to the same outcome.

The English summary is being prepared. Showing the original description.

s-smits/anabasis63Updated Oct 19, 2026

The harnesses a campaign keeps, read outside a run: which there are and where each came from, what each is made of and what moved from its parent, what each was measured to be, trying one on a task, the audit before a promotion and the blind review at a handover, whether a part earns its place, and changing what makes a harness or what a seat is told about one. Use when the operator asks which harness is current, what a Builder changed, whether a harness is ready to promote or hand over, to run a kept harness on a task, or to change the harness contract. Reading one run is whole-run-investigation's, wording a claim attribution-and-proof's.

The English summary is being prepared. Showing the original description.

s-smits/anabasis63Updated Oct 19, 2026

Hand a question about Anabasis v2 to an outside Oracle model as one task document and one zip. The Oracle reads GitHub; the zip carries what it cannot fetch: campaign logs and kept harnesses through `bun run runs zip`, a reader's output, predictions with how each resolved, patches for commits never pushed. Use when the operator asks to prepare an Oracle question, a report request, a problem statement or a second opinion on a run, a reading or a design, or to send the latest runs to an outside model. Produces local files; uploading is the operator's.

The English summary is being prepared. Showing the original description.

s-smits/anabasis63Updated Oct 19, 2026

Run the Anabasis v2 improvement loop, the Super Loop, towards more promotions in one fresh campaign: score the five points, read each campaign at its milestone, find the link of the promotion chain that holds it, fix that link's owner (a prompt, a tool result, the gate, the move table, a term), prove its path, put a prediction on record, launch a fresh campaign at the fixing commit, watch, read the log, decide. Use when the operator asks to keep campaigns going, to run a pass or the hourly audit, what to read at a promotion, when to run a whole-run investigation, why a campaign is not promoting, or what to launch next. Owns the choice of experiment and the reading of its evidence; the operator owns the level, a freeze, a stop, spend and the solve's condition.

The English summary is being prepared. Showing the original description.

s-smits/anabasis63Updated Oct 19, 2026

See all skills by s-smits

Report a problem with this skill