Skip to content

CC003 rejects correct imperative subjects: a word list cannot decide imperative mood #526

Description

@shenxianpeng

What happens

SubjectImperativeValidator takes the subject's first word and requires exact membership in the IMPERATIVES set:

# commit_check/engine.py:331
first_word = match.group(1).lower()
if first_word in IMPERATIVES:
    return ValidationResult.PASS
self._print_failure(subject)
return ValidationResult.FAIL

A verb missing from the list therefore fails a subject that is written correctly. This came up on commit-check-action#251, where

feat: settle the report format and stop the comment matcher deleting by title

was rejected. settle is the imperative form. It just was not in the list.

The cost falls on the contributor: they reword something that was never wrong, and the only way to discover which words are acceptable is trial and error. The error message doesn't help either — "Change the first verb to imperative form" is advice for a subject that is already in imperative form.

How large the gap is

Measured against 40,000 subjects from git.git — a project that writes strictly imperative subjects, with its area: prefixes stripped so only the leading verb is compared:

List Subjects rejected
396 words (before #TBD) 7,158 — 17.9%
529 words (after #TBD) 4,187 — 10.5%

Words that were being rejected: avoid (640 occurrences), clarify (207), factor (138), teach (129), free (93), mention (87), respect (74), plug (69), complete (63), settle, treat, restore, tighten, retire, inline

Two structural problems the additions do not solve

1. British spelling. The file had sixteen -ize verbs and four -ise ones. normalise, prioritise, standardise and friends were rejected outright. I have paired them up, but the asymmetry is a symptom: every future addition has to remember both spellings or the bug returns.

2. Adverb-led subjects. always quote the path, optionally skip the hook, explicitly close the handle are correct imperative English. A word list of verbs cannot represent them without becoming a list of not-verbs. I deliberately left these out — putting always into a set named IMPERATIVES would be lying about what the set contains.

Together these are why the remaining 10.5% cannot be closed by adding more words. Each release recognises a few more verbs — v2.12.2 already did this in #496 — and the next contributor finds the next gap.

Suggested direction

Invert the test: instead of asking "is this word on the list of imperatives", ask "is this word in a form that is definitely not imperative". The mood is detectable from morphology far more reliably than from vocabulary:

  • -ed past tense — updated, removed, fixed
  • -ing gerund — adding, fixing
  • third-person -sfixes, adds, updates

That is roughly what the rule is actually there to catch, and it needs no vocabulary at all. The word list can stay as a fast-path allow list for words that would otherwise trip the heuristic (address, process, bless end in s; speed, embed, feed end in ed; bring, ping, string end in ing) — those are exactly the cases a suffix rule gets wrong, and there are few enough of them to enumerate honestly.

A rejection would then mean the author really did write fixed instead of fix, which is the failure the rule exists for.

Happy to implement this if the direction seems right — it would be a behaviour change for anyone currently relying on the strictness, so it probably wants a minor version and a note in the changelog.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions