Repository navigation
Measure the capability list instead of maintaining it - #25
Merged
Merged
Conversation
The package doc and the README each list the optional capability interfaces, and both had drifted THREE behind: ModifiedClicker and ModifiedKeyer were added last without updating either, and NativeControlProvider had been missing for longer. A capability list that is wrong is worse than no list -- a reader who counts six does not go looking for a seventh, and NativeControlProvider was invisible to anyone reading the doc rather than run.go. So both lists are now checked against the code. TestEveryCapabilityIsNamedInThePackageDoc walks the package for type assertions off a Handler and insists each exported interface it finds is named where each document lists them. "A capability" is not a judgement in that test: it is an exported interface this package type-asserts, which is exactly what makes it optional. ⛔ The first version of the check was blind, and an ablation found it. It searched the WHOLE text, and the README names ModifiedKeyer twice -- once in the list, once in a paragraph explaining why it exists -- so removing it from the LIST left the prose to keep the check quiet. It now narrows to the paragraph that does the listing. Four rules, four witnesses, each verified to fail when its rule is ablated, including the one that previously passed. Also written down, in the README, why those two capabilities exist at all: Handler has nowhere to put a modifier key, so without them a Shift-click or a Shift-arrow cannot reach the widget underneath whatever that widget supports. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The package doc and the README each list the optional capability interfaces, and
both had drifted three behind:
ModifiedClickerandModifiedKeyerwere addedlast without updating either, and
NativeControlProviderhad been missing forlonger.
A capability list that is wrong is worse than no list — a reader who counts six
does not go looking for a seventh, and
NativeControlProviderwas invisible toanyone reading the doc rather than
run.go.So both lists are measured now
TestEveryCapabilityIsNamedInThePackageDocwalks the package for type assertionsoff a
Handlerand insists each exported interface it finds is named where eachdocument lists them. "A capability" is not a judgement in that test: it is an
exported interface this package type-asserts, which is exactly what makes it
optional.
⛔ The first version of the check was blind, and an ablation found it
It searched the whole text. The README names
ModifiedKeyertwice — once inthe list, once in a paragraph explaining why it exists — so removing it from the
list left the prose to keep the check quiet:
It now narrows to the paragraph that does the listing, and the same ablation
fails as it should.
Four rules, four witnesses, each verified to fail when its rule is ablated,
including the one that previously passed.
Also written down
Why those two capabilities exist at all, in the README:
Handlerhas nowhere toput a modifier key —
MouseDown(x, y int)carries no Shift, andKey's owncontract says it has "no room to say which modifiers were held" — so without
them a Shift-click or a Shift-arrow cannot reach the widget underneath whatever
that widget supports.
Everything outside the documented native-run-loop exclusion stays at 100.0%.
🤖 Generated with Claude Code