fix(tests): make the CLI-verb linter see leaf verbs and negative criteria - #2546
fix(tests): make the CLI-verb linter see leaf verbs and negative criteria#2546Cellcote wants to merge 1 commit into
Conversation
…eria `scripts/check-cli-verbs.py` reported clean on a task criterion demanding `uip pm apps model add-table` — a verb that does not exist (the CLI has `uip pm apps data-model add-table`). Two defects combined to hide it: - `enumerate_paths` treated `\b` as a partial match and trimmed the token it had just accumulated. A `\b` following a word character *confirms* the token ended, so this dropped the leaf verb from every `uip <group> <leaf>\b` pattern — the repo's standard shape — leaving only the command group verified. - `classify.best_match` then fell back to the parent group `pm apps model`, a real catalog entry, and reported reachable. Shortening to a shorter prefix is now refused when the leftover token sits in subcommand position under a group whose children the catalog knows. False positives are guarded three ways, each covered by a test: positional arguments after a leaf verb, partial kebab tokens (`create-` from a pattern matching `create-raw` / `create-resource`), and anything under an `unwalkable_groups` entry, whose children are unknown. Also scan `command_not_executed` (and `command_executed` bounded to `max_count: 0` — the other negative idiom here), which were skipped entirely. A negative whose verb does not exist can never fire, so it awards its weight unconditionally. These report Medium, not High: they inflate scores rather than breaking the run, and the guard is sometimes deliberate. Pin `encoding="utf-8"` on the file reads — the script crashed on Windows under cp1252. Against the current tree this yields 1 High (the process-mining task above, fixed separately) and 2 Medium (advisory, in uipath-governance). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Claude finished @Cellcote's task in 2m 42s —— View job PR Review: fix(tests): make the CLI-verb linter see leaf verbs and negative criteria
SummaryFixes three interacting defects in Change-by-Change Review1.
|
| Area | Status | Notes |
|---|---|---|
| Frontmatter | N/A | No skill files changed |
| E2E Tests | N/A | Not a skill change — this modifies a linting script and its unit tests |
| Skill Body | N/A | No skill files changed |
| References & Assets | N/A | No references or assets changed |
| Repo Hygiene | OK | No secrets, no cross-skill refs, changes are tightly scoped |
Issues for Manual Review
- The PR description mentions 2 Medium findings in
tests/tasks/uipath-governance/aops-policy/deployment_configure_smoke.yaml(negatives againstdeployment user add/add-user). These are out of scope for this PR but worth the governance skill owner investigating — they currently award weight unconditionally. - The merge ordering note is important: merge fix(process-mining): grade the real add-table verb and fix required tags #2545 first, otherwise the first repo-wide run reports a High on
uipath-process-mining(the bug this change is designed to catch).
Conclusion
Clean, well-motivated change that fixes a real scoring regression. The three defects are clearly diagnosed, each fix is narrow and well-tested (7 new tests with good false-positive guard coverage), and the existing 14 tests continue to pass. The encoding="utf-8" fix is a good defensive addition. No issues found that would block merge.
Split out of #2544 (part 2 of 2). Companion to #2545, which fixes the task this
change catches. Merge #2545 first — otherwise this PR's first repo-wide run
reports a High on
uipath-process-mining, which is the real bug, not aregression from this change.
Why
A process-mining task graded on
uip pm apps model add-table— a verb that doesnot exist (the CLI has
uip pm apps data-model add-table;apps modelis thesemantic model, with
fields/get/updateand noadd-tablechild). Itshipped, and it took a nightly score from 1.0 to 0.778, because
check-cli-verbs.pyreported the whole set clean. Two defects combined to hide it.1.
\bdiscarded the leaf verbOn
AT_BOUNDARYthe walker bailed and called_trim_to_word_boundary,dropping the token it had just accumulated. But
\bafter a word characterconfirms the token ended — it is the opposite of a partial match.
Since
uip <group> <leaf>\bis this repo's standard pattern shape, the checkerwas only ever validating the command group.
uip\s+pm\s+apps\s+model\s+add-table\b.*extracted as just
pm apps model.\Bkeeps the old behaviour: it asserts the token continues, so what wasaccumulated really is mid-token.
2. Longest-prefix matching swallowed bogus subcommands
best_matchthen fell back topm apps model, a real catalog group, andreported reachable. Shortening is now refused when the leftover token sits in
subcommand position under a group whose children the catalog knows.
3. Negative criteria were never verb-checked
iter_command_patternsonly yieldedcommand_executed. A negative whose verbdoes not exist can never fire, so it awards its weight on every run — a dead
assertion that inflates scores.
command_executedwithmax_count: 0is theother negative idiom in this repo and gets the same handling.
Negatives report Medium, not High: they inflate scores rather than breaking
the run, and the guard is sometimes deliberate (blocking a verb an agent might
invent).
Guarding against false positives
The prefix-shortening rule is deliberately narrow. Each of these is covered by a
test:
is resources run list <connector> <activity>.is resources run listhas no children, so the trailing tokens arearguments, not subcommands.
create-, left by a pattern matchingcreate-raw/create-resource. A trailing-means the walker stopped mid-token, so wecannot claim the verb is missing.
unwalkable_groups— the catalog builder could not enumerate them, soabsence from the catalog carries no information there.
Also
Pinned
encoding="utf-8"on the file reads. The script crashed withUnicodeDecodeErroron Windows under cp1252 when scanning task YAMLs containingem-dashes.
Verification
pytest tests/scripts/test_verb_checkers.py— 21 passed (14 existing + 7 new).The pre-existing
test_extract_verb_paths_treats_word_boundary_as_dynamicstillpasses: a
\breached before any complete token is still treated as dynamic.Medium, 124 Info. The High is exactly the process-mining bug this was written to
catch; with fix(process-mining): grade the real add-table verb and fix required tags #2545 merged it goes to 0.
.github/invokes this script./audit-verbsuses--report(exit 0 on Medium, per the contract inaudit-verbs.md) and/lint-taskmerges--jsonfindings.The 2 Medium findings are both in
tests/tasks/uipath-governance/aops-policy/deployment_configure_smoke.yaml—negatives against
deployment user add/add-user, which don't exist (the realverb is
configure, which auto-registers). Plausibly intentional guards; leftalone as out of scope, but worth a look from that skill's owner since they
currently award their weight unconditionally.
🤖 Generated with Claude Code