Skip to content

feat: check short flags - #12

Merged
silversurfer562 merged 2 commits into
mainfrom
claude/short-flag-support
Aug 11, 2026
Merged

feat: check short flags#12
silversurfer562 merged 2 commits into
mainfrom
claude/short-flag-support

Conversation

@silversurfer562

Copy link
Copy Markdown
Member

Only --long forms were scanned, so every -v in generated content was a silent pass. This is the last silent-pass class in the flag checker.

The easy half

A single-letter short flag is unambiguous — it is that flag or nothing — so an absent one is an error, exactly like a long flag.

The half that could have made the tool worse

A longer single-dash token has several valid readings:

Token Could be
-xzf a cluster of three flags (tar)
-name a single-dash long option (find, java)
-j4 a flag with an attached value (make)

Each reading is tried against --help — a cluster verifies when every letter is a known flag, an attached value when the leading flag is known. Only if none verifies is a finding emitted, and then as a warning, not an error: an ambiguous token is unverifiable, not refuted. That's the same rule the checker already applies to a command with no --help.

Splitting -name into four letter flags that don't exist would have been the obvious way to get this wrong, and it would have fired on every find example in every doc.

A dash followed by digits is not a flag. --threshold -5 reads -5 as the value it almost always is. The cost is that a numeric short flag (head -5) goes unchecked; the alternative false-positives on every negative number in a command line. Documented as a known limitation.

A latent bug the feature exposed

_flag_in_help bounded a match on the trailing side only. The trailing bound already stopped -v matching inside --verbose — but nothing stopped it matching the tail of --v, so a command whose help has only --v would report -v as verified. Both sides are now bounded. Covered by evasion_short_flag_hiding_in_long_flag.

Verification

Gate Result
Tests 173 passed (was 153)
Coverage 97%, flags.py 100%
Corpus precision/recall passing, 6 new regression cases
Mutation score 82.0% against the 75% gate (937 mutants, up from 890)
Lint ruff + black clean
Dogfood verify over its own README/CHANGELOG — no new errors, only the pre-existing "no help for command X" warnings

Version left at 0.4.0 with the entry under [Unreleased]; additive, so the next release is a 0.5.0 minor.

🤖 Generated with Claude Code

Only --long forms were scanned, so every '-v' in generated content was a
silent pass. The last silent-pass class in the flag checker.

A single-letter short flag is unambiguous — it is that flag or nothing —
so an absent one is an error, the same as a long flag.

A longer single-dash token is NOT unambiguous, and this is where the
feature could easily have made the tool worse. '-xzf' may be a cluster of
three flags; '-name' may be a single-dash long option (find, java); '-j4'
may be a flag with an attached value. Each reading is tried against
--help — a cluster verifies when every letter is a known flag, an
attached value when the leading flag is known — and only if none verifies
is a finding emitted, as a WARNING rather than an error. An ambiguous
token is unverifiable, not refuted, which is the same rule the checker
already applies to a command with no --help. Splitting '-name' into four
letter flags that do not exist would have been the obvious way to get
this wrong.

A dash followed by digits is read as the value it almost always is, so
'--threshold -5' does not treat '-5' as a flag. The cost is that a
numeric short flag ('head -5') goes unchecked; the alternative
false-positives on every negative number in a command line.

Also fixes a latent bug the feature exposed: _flag_in_help bounded a
match on the trailing side only, so '-v' matched the tail of '--v' and
reported a flag the command does not have as verified. Both sides are now
bounded. The trailing bound already stopped '-v' matching inside
'--verbose'; this closes the leading side.

173 tests pass, coverage 97% (flags.py 100%), mutation score 82.0%
against a 75% gate.
@silversurfer562
silversurfer562 force-pushed the claude/short-flag-support branch from c6dffc8 to fe76f48 Compare August 11, 2026 20:03
Promotes the short-flag work to a release. Additive feature -> minor
bump. Two version sites (pyproject, __init__) plus the changelog
promotion; the ruff>=0.4.0 dep floor and the historical corpus comment
are deliberately left alone.
@silversurfer562
silversurfer562 merged commit 3b91916 into main Aug 11, 2026
7 checks passed
Sign up for free to 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