Skip to content

Four measured ceilings and the dead code they found - #147

Merged
donislawdev merged 6 commits into
masterfrom
quality-gates-shape-and-dead-code
Aug 21, 2026
Merged

Four measured ceilings and the dead code they found#147
donislawdev merged 6 commits into
masterfrom
quality-gates-shape-and-dead-code

Conversation

@donislawdev

Copy link
Copy Markdown
Owner

What this is

Four ceilings and one clean-up, all measured on this tree rather than taken from a
textbook. Every number pinned here is today's maximum, so the whole set is green
from the first run and only fires when something grows past what already exists.

This started as a question about adopting an external complexity analyser. The
measurement said no: five of the six things that tool takes are taken here already,
often better, and its duplicate detector finds nothing in this tree - 168 files
scanned, zero logic clones, nine cross-file groups that are all data tables. Its
Python reader also counts and / or, which scores driver.doctor at 27 where
ruff scores the same function 6 - a ranking inversion on a flat table of ternaries.
A second, disagreeing number on an axis that already has one is two ceilings over
one head. So the gaps it did point at were closed with what is already installed.

The five commits

Remove five definitions nothing calls.BeanEngine.in_scope_now and the
BeanCore.in_scope behind it were recorded as unused when the connections page
moved its row highlight onto the stored scoped record; the follow-up the entry
promised never came. ScrollableFrame.yview_fraction, .set_yview_fraction and
PortTable.age have no caller anywhere and no mention in any document. Two comments
that described the deleted path were corrected - they claimed the highlight asks the
engine live, which it has not done for two releases.

A complexity crowd count.max-complexity watches one function and is blind to
the drift the size ratchet grew a second knob for: the runners-up climbing together,
none of them a record. At a ceiling of 29, cli._run_session could reach 29 from 27
with every gate green the whole way. Three functions are in the 70% band today and
the next one sits one branch below it.

PLR0913, and both rule lists held to each other. Argument count is the one
measurement on ruff's pylint-refactor list that nothing here already takes -
PLR0912 is C90 on the same function, PLR0915 is FUNCTION_CEILING measured worse
because the ratchet counts logic lines and leaves comments free, PLR0911 needs a
branch per return. Pinned to the widest signature that exists (14), not to ruff's
default of 5, which would be red on 25 signatures before catching anything.
--select on the workflow command line replaces the list in pyproject.toml, so a
rule could be configured, visible to ruff check locally, and absent from the only
run that can block a merge. Both lists are recorded in the suite now, and a third
check refuses a rule that is neither blocking nor reported.

A nesting-depth ceiling. The axis test_code_shape.py said out loud it did not
measure. Nothing else can see it: ruff has no depth rule, the size ceiling is blind
to it, and complexity scores a flat chain of eight elif exactly like eight nested
if. The band is absolute rather than a percentage - 70% of 5 lands on the same
line today, but at a ceiling of 4 it would mean "3 or more" and the count would jump
from 12 to 82.

A dead-code guard, resolved to a fixed point. A dead caller keeps its callee
looking alive, which is exactly how BeanCore.in_scope stayed invisible. The scan
reads an allow-list of trees and never walks the repository root, so it cannot reach
directories that exist on a maintainer machine and in no checkout - one that did
would call a name used locally and dead in CI.

Two things were wrong on the first attempt

Both were caught by measurement rather than review, and both are written down where
the next reader will hit them.

The depth metric walked an if body without adding the level that body sits at, so
four nested blocks measured three. Its own test found it - which is why the three
metric tests went in before any constant was filled in. The first pinned band (3)
was the wrong measurement and became 12 once the metric was fixed.

The dead-code guard scanned its own file, where the exception list lives, so writing
a name into that list was a mention of itself and the scan reported it as used. The
guard disarmed itself in the act of recording an exception, and the two entries on
that list were exactly the names it would have stopped watching.

Two measured decisions worth knowing about

The dead-code scan counts every word, comments and strings included. Counting only
code tokens finds six more names and five of them are alive: four are called from
inside run_gui("""...""") blocks - the GUI tests are Python source in a string, run
in a subprocess, and the suite holds 204 of those calls - and one is reached through
getattr. A guard that accuses living code is a guard people switch off. The price
is named in the file: a definition whose name is an ordinary English word survives on
prose alone, which is how PortTable.age had to be found by hand.

The three depth-metric tests are in PROVEN_BY_HAND, not MUTATIONS. Any patch to
the metric moves the measurement of the whole package, so it reddens the two ratchet
tests pinned to it as well - measured, three tests red at once - and a registry entry
names one test.

Verification

  • ruff check --select F,B,C90,PLR0913 . clean, mypy clean over 66 modules.
  • Guards for the touched code: 335 passed. Meta guards (shape, hygiene, registry,
    conventions, README, release, packaging): 97 passed. smoke_gui.py OK.
  • tools/mutate.py --changed for this branch: 29 entries, 29 caught, none survived.
    Six of those entries are new and each was run on its own as well.
  • End to end: a function nothing calls was planted in the package, the guard caught
    it by name, and the file was restored byte for byte.
  • Every pinned number was re-measured independently of the test that asserts it.

The full suite, the real-Tk render check, semgrep, diff-cover and the executable
build were deliberately left to this pull request - they need the platforms CI has.

donislawdevand others added 6 commits August 21, 2026 18:58
…ose that outlived them
`BeanEngine.in_scope_now` and the `BeanCore.in_scope` behind it were recorded as
unused when the connections page moved its row highlight onto the stored `scoped`
record; the removal that entry promised never happened.
`ScrollableFrame.yview_fraction`, `.set_yview_fraction` and `PortTable.age` have no
caller anywhere in the repository and no mention in any document.
Two comments claimed the row highlight asks the engine live whether a port is in
the target set. It has read the stored per-flow record for two releases - which is
exactly why the live call went unused - so both now describe `_tag_of` as it is.
Ahead of the dead-code guard, so the guard is pinned to a tree that is already
clean rather than to a number with a ten-minute shelf life.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…chet already had
`max-complexity` watches one function: the most branching one in the tree. It is
blind to the drift the size ratchet grew a second knob for on 2026-08-06 - the
runners-up climbing together, none of them a record. At a ceiling of 29,
`cli._run_session` could reach 29 from 27 with every gate green the whole way.
COMPLEX_NEAR_CEILING is today's count in the same 70% band: three functions reach
21 or more, and the next one sits at 20, so the band can fire rather than being a
number set where nothing can ever reach it.
Both halves live in one test because each reading costs a ruff subprocess over the
whole tree; `check` still gives each half its own wording. Measured repo-wide, like
the ceiling it is a percentage of.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… - argument count
PLR0913 is the only rule on ruff's pylint-refactor list that is not a second
number on an axis this repository already watches. PLR0912 scores `core.decide` at
30 where C90 scores the same function 29; PLR0915 is FUNCTION_CEILING measured
worse, because the ratchet counts logic lines and leaves comments free; PLR0911
needs a branch per return, which C90 has already counted. Complexity and length are
both blind to a wide signature: fifteen arguments can be four lines of
straight-line assignment.
Pinned to the widest signature that exists (14, sortable_tree.__init__), not to
ruff's default of 5, which would be red on 25 signatures before catching anything.
The two rule lists are now held to each other. `--select` on the workflow command
line replaces the list in pyproject.toml, so a rule could be configured, visible to
`ruff check` locally, and absent from the only run that can block a merge. Both
lists are recorded in the suite, and a third check refuses a rule that is neither
blocking nor reported. Both READMEs and CONTRIBUTING describe the gate as it is now.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…it did not measure
Length, branch count and indent depth are three different questions. Nothing else
here can answer the third: ruff has no depth rule (SIM102 and SIM117 collapse
joinable statements rather than measuring depth), the size ceiling is blind to it,
and max-complexity scores a flat chain of eight elif exactly like eight nested if.
The ceiling is 5 - a supersampling rasteriser that earns every level - with eleven
functions at 4 and 860 of 942 at 2 or less. The band is absolute rather than a
percentage: 70% of 5 lands on the same line today, but at a ceiling of 4 it would
mean "3 or more" and the count would jump from 12 to 82.
The metric was wrong when it was written and its own test is what caught it: an if
body was walked without the level it sits at, so four nested blocks measured three.
The three metric tests went in before the constants were filled in for exactly that
reason, and they live in PROVEN_BY_HAND because any patch to the metric reddens the
ratchet tests pinned to it as well - measured, three at once - and a registry entry
names one test.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…oint
A dead caller keeps its callee looking alive: BeanCore.in_scope had exactly one
caller in the tree and that caller was BeanEngine.in_scope_now, which nothing
called either. One pass sees a name mentioned twice and calls it used, so the scan
iterates - a mention counts as life only when it comes from somewhere alive.
The scan reads an allow-list of trees and never walks the repository root, so it
cannot reach directories that exist on a maintainer machine and in no checkout; one
that did would call a name used locally and dead in CI.
Two measured decisions are recorded in the file. It counts every word, comments and
strings included, because counting only code tokens finds six more names and five
are alive - four called from inside run_gui("""...""") blocks, one through getattr.
And it excludes its own file, because the exception list lives there and a name
written into it was a mention of itself, which disarmed the guard in the act of
recording an exception.
Both halves proven able to fail through the registry.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ctually fail
Three guards in tests/test_code_shape.py read a threshold out of pyproject.toml
and ask ruff whether anything crosses it. The mutation job installed the runtime
and dev requirements but not the lint ones, so those tests found no ruff, skipped,
and the runner reported SURVIVED for mutations that are caught anywhere ruff is
installed. Two entries came back that way on this branch with no defect behind
either.
The skip is now a visible pytest skip rather than a quiet return. A guard that
measured nothing has to look different from a guard that passed - which is the
whole point of the registry that surfaced this.
One anchor had to move: the entry proving that no workflow upgrades pip from the
index pointed at the bare lint-requirements install, unique only while one job
installed the linter. It matches twice now, so it is re-anchored on a command that
names two requirement files, which is unique for a reason unrelated to what the
entry guards.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@donislawdev
donislawdev merged commit 1c73c38 into masterAug 21, 2026
22 checks passed
@donislawdev
donislawdev deleted the quality-gates-shape-and-dead-code branch August 21, 2026 18:30
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@donislawdev