Skip to content

feat(claude-ops): audit-skill-visibility names misconfigured skills, longest descriptions, and next actions - #4107

Merged
kyle-sexton merged 3 commits into
mainfrom
claude/audit-skill-visibility-hxhyma
Sep 11, 2026
Merged

feat(claude-ops): audit-skill-visibility names misconfigured skills, longest descriptions, and next actions#4107
kyle-sexton merged 3 commits into
mainfrom
claude/audit-skill-visibility-hxhyma

Conversation

@kyle-sexton

@kyle-sexton kyle-sexton commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Closes #4105

Summary

The claude-ops:audit-skill-visibility Markdown report counted misconfigured skills without naming them, printed an overflow figure without showing which descriptions spend the budget, and ended with no pointer to what to do. Every field the tables need already sat in the JSON model. This is the last item from the session that scoped and fixed #4076, #4077 and #4078: it was agreed there and never filed.

Fix

  • Misconfigured table under Reachability: skill and cause, sorted by name, with each cause's remedy stated once below the table rather than once per row. The caption separates the two causes: malformed frontmatter loads with no metadata, a missing description falls back to the first body paragraph.
  • Longest competing descriptions under Listing budget, only when a row overflows: the ten longest by uncapped source length with the capped charge beside each, since the charge saturates at skillListingMaxDescChars and would order every over-cap description by name. Labelled as length and never as a starvation ranking, so an unscored run renders it unchanged and still withholds which skills lose theirs.
  • Next actions section at the end, built only from the conditions present (misconfigured rows, hidden plugins, an overflow, an unscored overflow); a clean run says there is nothing to fix. The overflow step names the budget control the run's provenance says is effective: SLASH_COMMAND_TOOL_CHAR_BUDGET when it overrides the fraction, the managed policy file when it supplied the fraction, otherwise the settings file that did; a --budget-fraction pin is called out as changing the report only.
  • Every table caps at ten rows and counts the rest, matching the renderer's existing convention. A small listing_overflows predicate is factored out of starvation_withheld and shared.
  • JSON schema 1.2.0, additive: each listing row carries description_chars (uncapped source length) beside the capped demand_chars.
  • plugins/claude-ops -> 0.53.0 with a CHANGELOG entry (0.52.0 was taken by feat(claude-ops): audit-performance projects hook fan-out per tool and file kind #4099 on main while this PR was in review); one paragraph added to SKILL.md's "Reading the output".

Verification

  • python3 -m unittest test_audit_skill_visibility: 148 tests, OK (140 -> 146 -> 148; new RenderTablesTest covers cause and per-cause remedy, the ten-row cap, no length table when the listing fits, source-length order above the cap with the charge shown, no likely-starved wording when unscored, the past-ten count, next actions naming only present conditions, and the effective budget control for the env override, a pin, a settings file, and managed policy).
  • scripts/run-ruff.sh check and format --check: clean. markdownlint-cli2 on SKILL.md and CHANGELOG.md: clean.
  • scripts/check-changelog-parity.sh --check, --check-bump origin/main, --check-preserved origin/main: clean on the merged tree. check-purged-em-dashes.sh: no em dashes.
  • scripts/affected-tests.sh --run on the merged tree: four shell suites PASS (both audit-skill-visibility suites plus the two selected by the merged audit-performance change); the Python lane is a NOT RUN ecosystem by design and was run directly.
  • Live smoke on this checkout: at a pinned 200k/4 window the length table lists the ten longest descriptions with their charge and "and 185 more competing", and the next-actions line names the project settings file that set the fraction to 0.05; with SLASH_COMMAND_TOOL_CHAR_BUDGET exported it names the env override instead; at 1M/4 no length table renders and the line reads "Nothing to fix from this run."
  • Codex review: three P2 findings verified and fixed in c2ab9c5 (see the threads).

Related

🤖 Generated with Claude Code

https://claude.ai/code/session_013GSKHZcGv3r3p6gpc8N8ai

…longest descriptions, and next actions

The Markdown report counted misconfigured skills without naming them,
printed an overflow figure without showing which descriptions spend the
budget, and ended with no pointer to what to do. All three fields already
sat in the JSON model, so the renderer now tables them: misconfigured
skills with their cause and one remedy per cause under Reachability; the
ten longest competing descriptions with character counts under Listing
budget whenever a row overflows, labelled as description length and never
as a starvation ranking so an unscored run renders it unchanged; and a
closing Next actions section built only from the conditions present.
Every table caps at ten rows and counts the rest. The JSON is unchanged.

Release claude-ops 0.52.0.

Closes #4105

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013GSKHZcGv3r3p6gpc8N8ai
@kyle-sexton
kyle-sexton marked this pull request as ready for review September 11, 2026 17:03
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 11, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-11T17:07:01.905565Z 5459a1e Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@claude

claude Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 1m 35s —— View job


Code review complete

  • Gather context (PR diff, changed files, CLAUDE.md/AGENTS.md)
  • Apply skip gate (open, not draft, meaningful diff, no existing applicable review)
  • Review changed files against /review:code-review criteria
  • Adversarially validate candidate findings
  • Post inline comments for anchorable findings
  • Final summary update

Summary

Reviewed the diff (git diff origin/main...HEAD) across all 5 changed files per the /review:code-review criteria (correctness, maintainability, alignment with AGENTS.md/CLAUDE.md, no untouched-line nits, security out of scope for this lane).

No blocking findings. The change is a clean, behavior-preserving extraction plus three new render helpers:

  • listing_overflows is correctly factored out of starvation_withheld with identical logic (audit_skill_visibility.py#L1771-L1776), reused correctly at both call sites (starvation_withheld and _render_next_actions).
  • _render_misconfigured sorts by qualified_name, caps at 10 rows with a "…and N more" count, and keys the remedy by cause (verified MISCONFIGURED_REMEDIES only ever contains the two causes reachability() can produce, so no KeyError risk).
  • _render_longest ranks by demand_chars descending with a qualified_name tiebreak, is gated on any_overflow so it never renders on a fitting listing, and is careful in its own docstring/label not to be read as a starvation ranking — matching the PR's stated intent that this renders identically whether the run is scored or unscored.
  • _render_next_actions builds steps only from conditions actually present in the model (misconfigured, hidden, listing_overflows, score_basis == "unscored"), and correctly falls back to "Nothing to fix from this run." — matches the "clean run says there is nothing to fix" claim in the PR description.
  • SKILL.md and CHANGELOG.md updates accurately describe the new behavior; version bump (0.51.00.52.0) is consistent with the change.

I could not independently execute python3 -m unittest test_audit_skill_visibility or scripts/run-ruff.sh in this environment (Bash access in this lane is scoped to gh pr * per this skill's allowed-tools), so the PR's stated test/lint verification is author-claimed and unverified by me — I confirmed correctness by reading the new RenderTablesTest cases against the implementation, and the assertions line up with what the code does (e.g. cause-per-row + one remedy per unique cause, 10-row cap with overflow count, no length table when nothing overflows, descending demand_chars order with no likely-starved wording when unscored).

No inline comments posted — no findings met the high-signal bar (a careful reviewer would block or flag).

@claude

claude Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 1m 2s —— View job


Security review — /review:security-review

  • Gather context (PR diff, changed files)
  • Apply skip-gate check
  • Review changed files for security-relevant surface
  • Post findings

No security issues found.

This PR only changes Markdown rendering in audit_skill_visibility.py (plugins/claude-ops/skills/audit-skill-visibility/scripts/audit_skill_visibility.py): a misconfigured-skills table, a longest-competing-descriptions table, and a next-actions summary, plus the corresponding SKILL.md doc, CHANGELOG entry, version bump, and new tests. No subprocess/shell execution, no network calls, no file writes, no eval/exec, and no changes to auth, access control, secrets, or trust boundaries. The new f-string table rows (_render_misconfigured, _render_longest) interpolate qualified_name/causes/demand_chars the same way the pre-existing _render_reachability table already does, so there's no new injection surface — this is plain text formatted into Markdown, not HTML/SQL/shell context. --render json output is unchanged.

Skip-gate criterion 2 applies: no security-relevant surface in this diff.

@github-actions

Copy link
Copy Markdown
Contributor

Last security-reviewed head: 5459a1e162be665ce8b7f82e1507bbae7c0cf7d1. On the next push, the relevance gate compares only the commits since this SHA; delete this comment to force a full re-review.

@github-actions

Copy link
Copy Markdown
Contributor

Claude has reviewed this PR 1 time. The lane skips further automatic reviews after 5; deleting this comment resets the count.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5459a1e162

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

…t actions at the effective budget control

Three review findings on the new render tables. The length table ranked
on the capped charge, so every description over skillListingMaxDescChars
tied at the cap and sorted by name; each listing row now also carries the
uncapped description_chars, the table ranks on it with the charge shown
beside it, and the caption says trimming lowers the overflow only under
the cap. The next-actions line always recommended raising the fraction,
which cannot move the overflow when SLASH_COMMAND_TOOL_CHAR_BUDGET
overrides it, when a --budget-fraction pin changed only the report, or
when managed policy supplied it; it now names the control the provenance
says is effective. The misconfigured caption claimed a skill could never
match, which is true of malformed frontmatter and false of a missing
description, since the product falls back to the first body paragraph;
it now states both. JSON schema 1.2.0, additive.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013GSKHZcGv3r3p6gpc8N8ai
…sibility-hxhyma

# Conflicts:
#	plugins/claude-ops/CHANGELOG.md
@kyle-sexton
kyle-sexton merged commit 3b273a2 into main Sep 11, 2026
18 checks passed
@kyle-sexton
kyle-sexton deleted the claude/audit-skill-visibility-hxhyma branch September 11, 2026 17:25
kyle-sexton added a commit that referenced this pull request Sep 11, 2026
…n prose across 36 skills (#4108)

No related issue: this closes the one decision the audit behind #4072
reclassified to a human, resolved by re-reading the sources; no issue
tracks it.

## Summary

Anthropic's [skill-authoring best-practices
page](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices#writing-effective-descriptions)
rules out first and second person in a skill description. Its two Avoid
examples are "I can help you process Excel files" and "You can use this
to process Excel files", and its reason is that the text is injected
into the system prompt. Its own effective examples, the Claude Code
skills page's examples, and the bundled skill-creator's frontmatter are
all imperative ("Extract text and tables from PDF files", "Fix a GitHub
issue", "Create new skills..."), so imperative and third-person singular
both conform and this marketplace's imperative descriptions are not a
deviation. The real gap was description prose that addresses the reader.
A scripted scan that strips quoted trigger phrases and hyphenated or
slash-joined identifiers found it in 36 skills across 24 plugins.

## Fix

- **36 skill descriptions** (adhd, bugs, claude-config, claude-ops,
code-metrics, discipline, discovery, docs-hygiene, education, firecrawl,
improvement, instruction-placement, kindle-dedrm, mutation-testing,
overengineering, playgrounds, plugin-quality, prototype, session-flow,
songwriting, source-control, tdd): each clause that addressed the reader
now names the user, the session, the assistant, or the repository.
Examples: "so you can act on it" becomes "so the reader can act on it";
"a permission rule you cannot locate" becomes "a permission rule whose
source is unknown"; "books you own" becomes "books the user owns";
"synthesize where we stand" becomes "synthesize where the session
stands". Quoted trigger phrases (user utterances such as 'audit my
.claude folder'), backticked tokens, slash tokens, and skill names are
byte-identical. No description grew by more than 20 codepoints or
crossed 1,024; two that sat near the cap got shorter.
- **One clause stays as it was.** The native-surface presence gate
("resolves in your session") in the two claude-ops descriptions
(`audit-install-state`, `audit-skill-visibility`) is a literal token the
native-overlap registry self-check matches against every baked store
row, so `validate-plugins.sh` fails when it is reworded (that is what
turned `7cbf30ab8` red). Commit `af0e7b274` restores the token in both
and the claude-ops changelog entry says why. Changing the token itself
touches the checker, its tests, twelve skills, the seam-phrasing
convention, and the store evidence, and is tracked as #4112.
- **Two plugin manifests** (kindle-dedrm, session-flow) carried the same
wording in their own descriptions and follow; `docs/CATALOG.md`
regenerated.
- **playbooks 0.11.2**:
`skill-authoring/reference/authoring-guidance.md` states the rule as the
page defines it, with the Avoid examples, the system-prompt reason, and
the finding that imperative conforms, and its Record cites the three
imperative example surfaces with a recheck trigger for the page
rewriting its examples. `reference/authoring-checklist.md` gains the
matching judgment row. The previous text called the fleet's imperative
voice a deviation to leave alone, which the sources do not support.
- Each of the 24 touched plugins gets a patch bump and a CHANGELOG entry
naming its rewritten skills. Main moved four times while this was open;
the merge commits `2cc1102c0`, `f082ed2f8`, `7cbf30ab8`, and `0b10ccae7`
restack this change's entries above the newer main entries: claude-ops
to 0.54.1 (above #4099, #4107, and #4092), code-metrics to 0.2.3 (above
#4098), source-control to 0.55.76 (above #4106). Every other plugin's
bump is unchanged.

## Verification

Run on Linux at head `0b10ccae7`:

- Voice scan over all 258 skill descriptions (quoted phrases and
identifiers stripped, then first and second person pronouns matched): 36
hits before; after, only the two claude-ops descriptions that carry the
checked gate token (3 occurrences of that token, nothing else). An
uppercase variant scan finds 0.
- `scripts/validate-plugins.sh`: passes; the native-overlap self-check
reports degraded (stale-but-honest advisories, the same as main), not
broken.
- `scripts/check-changed-skills.sh origin/main`: 35 skills checked, 0
failed, no dropped-trigger-keyword WARN on any skill (check 3 compares
every trigger phrase against the base ref).
- `check-changelog-parity.sh --check`, `--check-bump origin/main`,
`--check-order`: pass across all 93 changelogs. `generate-catalog.mjs
--check`: in sync.
- `markdownlint-cli2` over every changed markdown file: 0 issues.
`typos` over the added lines: clean. `check-purged-em-dashes.sh`: no em
dashes.
- Diff shape: 36 SKILL.md files touched on their description line only,
23 plugin.json version bumps plus the two manifest description edits, 23
CHANGELOG.md entries, the two playbooks spokes, and the catalog. No
skill body, script, or test changed.
- `scripts/affected-tests.sh --run`: no suites selected (every changed
file is a recorded no-suite class).
- CI: `ci-status` and every lane green on `45af55489` (draft) and on
`2cc1102c0` (draft and after the ready flip). Codex review on
`2cc1102c0`: completed, no findings. `7cbf30ab8` went red on
`test-linux` (the gate-token self-check above); `af0e7b274` carries the
fix and `0b10ccae7` merges the latest main on top.

## Related

- Follow-up to #4069 and #4072. The two fresh-context validators behind
#4072 both reclassified the description-voice row to a human decision on
the premise that imperative and third person are two voices; re-reading
the page's examples shows they are one conforming class, so the decision
resolves on evidence rather than taste. The reasoning and the scan live
in the untracked
`.work/skill-authoring-best-practices/INTERVIEW-ACCEPTED.md` ("Audit
resolution", row I1.2) of the authoring checkout.
- #4112 tracks retokening the presence gate so the last two descriptions
lose their second person too.
- #4070 and #4071 remain the deferred follow-ups from #4069.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01MSGD4WGhUXepHq3LTmpQML

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants