Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/CATALOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ plugin manifests and kept in sync by CI — never hand-edit it; the category voc
- [`context-guard`](../plugins/context-guard) — Per-session context-window observability plus the first shipped consumer: a statusline wrapper tees each session's context_window fields to a per-session snapshot file, a zone resolver classifies usage into smart/acceptable/dumb bands (percentage bands plus window-class token bands, conservative-min combination, zones.json SSOT with shipped defaults), a reader contract fixes how consuming sessions interpret the snapshots, and zone-crossing hooks report once per transition into a worse zone across two channels — the continuation menu to the operator, who owns that choice, and to the model only the zone determination plus the counter-steer that a zone word is not a decay signal (advisory by default; an optional blocking mode gates new mutating work on a fresh dumb-zone snapshot with handoff-writing exempt), with a PostCompact hook persisting an evidence-degraded marker.
- [`context-budget`](../plugins/context-budget) — Measure a Claude Code session's fixed startup context payload per item, on the consumer's machine at a pinned, version-stamped binary — including per-tool attribution of the built-in tool pools that /context reports only as lump sums, derived live by A/B bare-name-deny differencing with enforced comparability rules (skill-listing signature, one mode, one binary), an SDK-primary exact meter degrading to a version-aware headless /context parser and then to an honest structured error (never a wrong number), and a per-project measure-toggle-remeasure ledger under the plugin data directory recording every lever's real before/after delta. Report-only: prints exact config, applies nothing.
- [`plugin-quality`](../plugins/plugin-quality) — Post-use behavioral audit of Claude Code plugin components: a six-step audit workflow (evidence capture, grounded mapping in a fresh subagent, blindspot pass, interactive contract lock, presence-gated review seams, work-item emit with draft+confirm) over any skill, agent, hook, command, or config you have actually used — zone-informed by context-guard snapshots when present, conservative when not.
- [`skill-quality`](../plugins/skill-quality) — Skill-authoring QA tooling: a static contract checker that runs twenty-two deterministic checks over a Claude Code skill (frontmatter, per-skill listing-entry cap, trigger-keyword preservation, line caps, broken internal refs, markdownlint, gotchas surface, evals presence, precompute opportunity, injection shell-declaration, fresh-eyes declaration conformance), a shared skill-listing budget reporter across a set of skills, and a bundled evals.json schema plus a deterministic eval-quality lint (duplicate case identities, missing fixtures, empty or vague grading criteria, set-coverage warnings). Runs against any repo's skills directory via the convention-resolution ladder — no baked layout.
- [`skill-quality`](../plugins/skill-quality) — Skill-authoring QA tooling: a static contract checker that runs twenty-three deterministic checks over a Claude Code skill (frontmatter, per-skill listing-entry cap, trigger-keyword preservation, line caps, broken internal refs, markdownlint, gotchas surface, evals presence, precompute opportunity, completion-criteria signal, injection shell-declaration, fresh-eyes declaration conformance), a shared skill-listing budget reporter across a set of skills, and a bundled evals.json schema plus a deterministic eval-quality lint (duplicate case identities, missing fixtures, empty or vague grading criteria, set-coverage warnings). Runs against any repo's skills directory via the convention-resolution ladder — no baked layout.
- [`computer-use`](../plugins/computer-use) — Operating knowledge for Claude Code's built-in computer-use MCP server — the desktop screen-control surface. `/computer-use:diagnose` resolves a symptom to a cause instead of retrying: why every screenshot is downscaled to a fixed pixel budget and why zoom (not a bigger display) is the way back to detail, how to read a capture or input failure, and the per-OS quirks that make a synthesized key or menu behave unlike a human's. `/computer-use:setup` verifies the prerequisites the surface cannot verify for itself and reports the environment settings that end a session mid-run.

## Autonomy
Expand Down
4 changes: 2 additions & 2 deletions plugins/skill-quality/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
"name": "skill-quality",
"version": "0.15.13",
"description": "Skill-authoring QA tooling: a static contract checker that runs twenty-two deterministic checks over a Claude Code skill (frontmatter, per-skill listing-entry cap, trigger-keyword preservation, line caps, broken internal refs, markdownlint, gotchas surface, evals presence, precompute opportunity, injection shell-declaration, fresh-eyes declaration conformance), a shared skill-listing budget reporter across a set of skills, and a bundled evals.json schema plus a deterministic eval-quality lint (duplicate case identities, missing fixtures, empty or vague grading criteria, set-coverage warnings). Runs against any repo's skills directory via the convention-resolution ladder \u2014 no baked layout.",
"version": "0.16.0",
"description": "Skill-authoring QA tooling: a static contract checker that runs twenty-three deterministic checks over a Claude Code skill (frontmatter, per-skill listing-entry cap, trigger-keyword preservation, line caps, broken internal refs, markdownlint, gotchas surface, evals presence, precompute opportunity, completion-criteria signal, injection shell-declaration, fresh-eyes declaration conformance), a shared skill-listing budget reporter across a set of skills, and a bundled evals.json schema plus a deterministic eval-quality lint (duplicate case identities, missing fixtures, empty or vague grading criteria, set-coverage warnings). Runs against any repo's skills directory via the convention-resolution ladder \u2014 no baked layout.",
"author": {
"name": "Melodic Software",
"email": "info@melodicsoftware.com"
Expand Down
18 changes: 18 additions & 0 deletions plugins/skill-quality/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,24 @@
All notable changes to the `skill-quality` plugin are documented here. Format follows
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this plugin uses semantic versioning.

## [0.16.0]

### Added

- **`check`: Check 23 — completion-criteria signal (WARN; advisory heuristic; #2963).** Flags a
numbered procedure of three or more steps (outside fenced code blocks) whose text carries no
completion-criteria signal token — the premature-completion shape where a step is markable
done at the first plausible output. Detects only the absence of any done-condition, never
grades a stated criterion; broad token set, so only genuinely signal-free procedures fire.
Fence-aware for both CommonMark fence forms with matching-marker close semantics;
independent lists split at a numbering restart across a blank line (loose ascending lists
stay one block). Seven test cases: signal-free warns, done-condition silent, both fence
forms ignored, mixed fence markers stay masked, adjacent short lists split, loose list
still warns.
The audit-side half of the course lane 7 completion-criteria adoption — the write-side
doctrine is `docs-hygiene:write-for-agents` 0.17.0 (#2962), and the check's SKILL.md gotcha
entry points authors there via the Skill tool.

## [0.15.13]

### Added
Expand Down
59 changes: 59 additions & 0 deletions plugins/skill-quality/scripts/check-skill.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1266,6 +1266,65 @@ if [[ -n "$CUR_SUMMARY" ]]; then
fi
fi

# --- Check 23: completion-criteria signal (WARN; advisory heuristic) ----------
# Flags a numbered procedure (three or more ordered-list steps outside fenced
# code blocks) whose text carries no completion-criteria signal — no observable
# done-condition a reader can test. A step without one invites premature
# completion: the model marks it done at the first plausible output. Advisory
# only: a static scan can detect the ABSENCE of any completion signal, never
# grade the quality of a criterion, and an illustrative list is
# indistinguishable from an operative one — so the signal tokens are
# deliberately broad and only genuinely signal-free procedures fire.
# Write-side doctrine: docs-hygiene:write-for-agents ("Give every step a
# completion criterion").

CC_SIGNAL='done|complete|verified|verify|confirm|assert|exit|pass|green|criteria|criterion|until|settle|expect|observable|observed|succeed|fail'
# Blank lines separate LOOSE list items without closing the block — but a
# numbered item that RESTARTS numbering (its number <= the previous item's)
# after a blank line is a new, independent list, and merging the two would
# both fire a spurious warn on adjacent short lists and let one list's signal
# clear the other. Side effect, accepted: an all-ones-numbered LOOSE list
# (CommonMark lazy numbering, blank lines between items) closes at every item
# and so under-reports — consistent with the advisory posture above.
CC_BLOCKS="$(awk -v sigre="$CC_SIGNAL" '
function close_block() {
if (steps >= 3 && !sig) bad = bad (bad ? "," : "") start "-" last
steps = 0; sig = 0; had_blank = 0
}
/^[[:space:]]*(```|~~~)/ {
m = ($0 ~ /^[[:space:]]*```/) ? "b" : "t"
if (!fence) { fence = 1; fence_ch = m } else if (m == fence_ch) fence = 0
next
}
fence { next }
{
lower = tolower($0)
if ($0 ~ /^[[:space:]]*[0-9]+[.)][[:space:]]/) {
n = $0
sub(/^[[:space:]]*/, "", n)
sub(/[.)].*$/, "", n)
n = n + 0
if (steps > 0 && had_blank && n <= last_n) close_block()
if (steps == 0) start = NR
steps++; last = NR; last_n = n; had_blank = 0
if (lower ~ sigre) sig = 1
} else if ($0 ~ /^[[:space:]]*$/) {
had_blank = 1
} else if (steps > 0 && $0 ~ /^[[:space:]]+[^[:space:]]/) {
last = NR; had_blank = 0
if (lower ~ sigre) sig = 1
} else {
close_block()
}
}
Comment thread
kyle-sexton marked this conversation as resolved.
END { close_block(); print bad }
' "$SKILL_MD")"
if [[ -n "$CC_BLOCKS" ]]; then
warn "numbered procedure(s) at lines $CC_BLOCKS carry no completion-criteria signal — steps risk premature completion; give each step an observable done-condition (write-side doctrine: docs-hygiene:write-for-agents)"
else
note "completion-criteria signal present (or no 3+-step numbered procedure)"
fi

# --- Summary ---------------------------------------------------------------

printf '\n'
Expand Down
189 changes: 189 additions & 0 deletions plugins/skill-quality/scripts/check-skill.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2573,6 +2573,195 @@ else
fail "outside git with no skills root should exit 2 (rc=$rc): $out"
fi

# 23a. A numbered procedure of 3+ steps with no completion-criteria signal
# token anywhere in the block warns (advisory) but passes.
make_skill cc-signal-missing '---
name: cc-signal-missing
description: "Rotate the config. Use when: '"'"'rotating the config'"'"'."
---

## Steps

1. Open the config file.
2. Update the rotation value.
3. Save the file.

## Gotchas

None known.
'
out="$(run cc-signal-missing 2>&1)"
rc=$?
if [[ $rc -eq 0 ]] && grep -q 'completion-criteria signal' <<<"$out"; then
pass "3-step procedure without any completion signal warns (completion-criteria)"
else
fail "signal-free numbered procedure should warn (rc=$rc): $out"
fi

# 23b. The same procedure whose final step states an observable done-condition
# is silent — the block carries a completion signal.
make_skill cc-signal-present '---
name: cc-signal-present
description: "Rotate the config safely. Use when: '"'"'rotating the config safely'"'"'."
---

## Steps

1. Open the config file.
2. Update the rotation value.
3. Save the file; the step is done when `validate --config` exits 0.

## Gotchas

None known.
'
out="$(run cc-signal-present 2>&1)"
rc=$?
if [[ $rc -eq 0 ]] && ! grep -q 'completion-criteria signal.*no completion' <<<"$out" && ! grep -q 'carry no completion-criteria signal' <<<"$out"; then
pass "procedure with a done-condition does not warn (completion-criteria)"
else
fail "signal-carrying procedure should not warn (rc=$rc): $out"
fi

# 23g. A literal ~~~ line inside a backtick fence does not close it — the
# numbered list after it is still masked (matching-marker close semantics).
make_skill cc-signal-mixed-fence '---
name: cc-signal-mixed-fence
description: "Show fence forms. Use when: '"'"'showing fence forms'"'"'."
---

## Example

```markdown
You can also use ~~~ fences:

~~~text
1. Open the config file.
2. Update the rotation value.
3. Save the file.
~~~
```

## Gotchas

None known.
'
out="$(run cc-signal-mixed-fence 2>&1)"
rc=$?
if [[ $rc -eq 0 ]] && ! grep -q 'carry no completion-criteria signal' <<<"$out"; then
pass "literal tilde markers inside a backtick fence stay masked (matching-close)"
else
fail "mixed fence markers should not unmask fenced content (rc=$rc): $out"
fi

# 23e. Two independent 2-step lists separated only by a blank line do NOT merge
# into one 4-step block — numbering restart after a blank closes the block.
make_skill cc-signal-adjacent '---
name: cc-signal-adjacent
description: "Two short flows. Use when: '"'"'running two short flows'"'"'."
---

## Flow A then flow B

1. Open the first file.
2. Update the first value.

1. Open the second file.
2. Update the second value.

## Gotchas

None known.
'
out="$(run cc-signal-adjacent 2>&1)"
rc=$?
if [[ $rc -eq 0 ]] && ! grep -q 'carry no completion-criteria signal' <<<"$out"; then
pass "adjacent 2-step lists split at the numbering restart (no spurious warn)"
else
fail "adjacent short lists should not merge into a warnable block (rc=$rc): $out"
fi

# 23f. A LOOSE ascending list (blank lines between items, numbering continues)
# is still ONE block — a signal-free 3-step loose procedure warns.
make_skill cc-signal-loose '---
name: cc-signal-loose
description: "Rotate the loose config. Use when: '"'"'rotating the loose config'"'"'."
---

## Steps

1. Open the config file.

2. Update the rotation value.

3. Save the file.

## Gotchas

None known.
'
out="$(run cc-signal-loose 2>&1)"
rc=$?
if [[ $rc -eq 0 ]] && grep -q 'carry no completion-criteria signal' <<<"$out"; then
pass "loose ascending 3-step list stays one block and warns when signal-free"
else
fail "loose signal-free procedure should still warn (rc=$rc): $out"
fi

# 23d. A signal-free numbered list inside a TILDE-fenced code block is ignored
# (both CommonMark fence forms are illustrative content).
make_skill cc-signal-tilde '---
name: cc-signal-tilde
description: "Show a tilde sample plan. Use when: '"'"'showing a tilde sample plan'"'"'."
---

## Example output

~~~text
1. Open the config file.
2. Update the rotation value.
3. Save the file.
~~~

## Gotchas

None known.
'
out="$(run cc-signal-tilde 2>&1)"
rc=$?
if [[ $rc -eq 0 ]] && ! grep -q 'carry no completion-criteria signal' <<<"$out"; then
pass "tilde-fenced numbered list is ignored by the completion-criteria heuristic"
else
fail "tilde-fenced list should not fire the completion-criteria warn (rc=$rc): $out"
fi

# 23c. A signal-free numbered list inside a fenced code block is ignored
# (illustrative content never fires the heuristic).
make_skill cc-signal-fenced '---
name: cc-signal-fenced
description: "Show a sample plan. Use when: '"'"'showing a sample plan'"'"'."
---

## Example output

```text
1. Open the config file.
2. Update the rotation value.
3. Save the file.
```

## Gotchas

None known.
'
out="$(run cc-signal-fenced 2>&1)"
rc=$?
if [[ $rc -eq 0 ]] && ! grep -q 'carry no completion-criteria signal' <<<"$out"; then
pass "fenced numbered list is ignored by the completion-criteria heuristic"
else
fail "fenced list should not fire the completion-criteria warn (rc=$rc): $out"
fi

if [[ $fails -ne 0 ]]; then
printf '%d assertion(s) failed\n' "$fails" >&2
exit 1
Expand Down
Loading