28 Commits
Author SHA1 Message Date
coolTheWorldandClaude Opus 5 b293c02481 ci: add a gate for references/ links in skills
The path fix has no regression guard: nothing in CI resolves references/
links, so all 18 were broken while CI stayed green. validate-artifact-
paths.js is scoped to spec/plan/todo artifacts and says in its own header
that it is not a general markdown path linter.

Add validate-reference-links.js, which resolves every `references/*.md`
link in skills/*/SKILL.md against that skill's own directory. This accepts
both conventions in CLAUDE.md: shared checklists reached via
../../references/, and a skill's own colocated references/ directory.

Scope stays narrow on purpose. Skills legitimately name paths that do not
exist yet -- tasks/todo.md, PERF.md, docs/ideas/[idea-name].md -- and a
general markdown linter would fail the build on them. A test pins that.

Proven against the pre-fix tree: 18 error(s), exit 1, matching the 18
links fixed in the previous commit. After the fix: 0 error(s), exit 0.

7 unit tests cover the regression itself, colocated references/,
markdown-link syntax, a renamed target, multiple violations in one skill,
and the non-reference paths that must be ignored. Wired into the
validate-skills job, alongside the other skill-content checks.

Known limitation: fenced code blocks are not stripped, so a SKILL.md that
documents the anti-pattern inside a fence would be flagged. Nothing does
today. Sharing stripFencedCodeBlocks looks right once #444 lands.

Refs #468

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 07:27:44 -04:00
Addy OsmaniandGitHub d2478bf0c7 Merge #458: clean up throwaway eval workspaces
fix: clean up throwaway workspace directories after eval runs
2026-08-06 15:44:15 -07:00
Addy OsmaniandGitHub 2211c9db0a Merge #456: validate --behavioral skill name
security: validate --behavioral skillName to prevent path traversal
2026-08-06 15:44:11 -07:00
Addy OsmaniandGitHub d915f004ce Merge #464: guard spec/plan/todo artifact paths
ci: guard spec/plan/todo artifact paths against silent drift
2026-08-06 15:43:58 -07:00
Joan Leon ce5e12bd5a ci: add validator guarding spec/plan/todo artifact paths
The /spec and /plan commands write spec, plan, and todo artifacts to paths that /build and the spec/plan skills read back. When a producer moves an artifact without updating the consumers, the pipeline breaks and nothing in CI catches it: the command-parity check only compares descriptions, not paths. PR #93 hit exactly this, pointing /spec and /plan at docs/features/[name]/ while /build still required SPEC.md and tasks/plan.md.

validate-artifact-paths.js enforces one canonical set of artifact paths across every file in the pipeline (the spec/plan/build commands, the spec-driven-development and planning-and-task-breakdown skills, and the getting-started and adoption guides). Any spec/plan/todo artifact path outside the allowlist fails CI, so changing the convention has to touch the allowlist and every guarded file in the same change.

Scope is deliberately narrow: only spec/plan/todo artifacts, only the pipeline files; it is not a general markdown path linter. Wired into the validate-commands CI job alongside its test.
2026-08-07 00:02:47 +02:00
Sunil 21fea4d528 fix: clean up throwaway workspace directories after eval runs
materializeWorkspace() creates directories in os.tmpdir() but
runBehavioral() never cleans them up on success or failure. If
execFileSync throws (timeout, signal, OOM), the workspace persists
in /tmp indefinitely with fixture data. The test file
run-evals-test.js uses try/finally cleanup (line 234), proving
the pattern was known but omitted in production code.

Fix: Wrap eval execution in try/finally with best-effort
fs.rmSync cleanup.
2026-08-05 22:37:48 +05:30
Sunil 4b3122e65f security: validate --behavioral skillName to prevent path traversal
The skillName argument from --behavioral has zero validation and is
used directly in path.join() for reading .json files, reading
SKILL.md, and WRITING .grading.json results. A value like
'../../etc/passwd' traverses outside the project directory for
both reads and writes.

Fix: Validate skillName against /^[a-z0-9]+(-[a-z0-9]+)*$/ before
any filesystem operations. This matches the existing KEBAB_CASE
validation in skill-lint.js.
2026-08-05 22:35:47 +05:30
LiyukandGitHub 0663a4e6e8 Fix plugin manifest version consistency 2026-08-04 08:01:41 -07:00
LiyukandGitHub a58fb3c319 Fix plugin manifest version consistency 2026-08-04 08:01:30 -07:00
ayobamiseun 4063947e3f test: cover command validator behavior 2026-08-01 10:41:53 +01:00
Kevin GlynnandCursor f25f467e7b fix(validator): reject fenced-block headings and negated triggers (#387)
Two heuristic bugs in the section and trigger checks, surfaced in
addyosmani#387 and triaged by @addyosmani and @nucliweb:

Section check: content.includes('## Overview') matches headings inside
fenced code blocks and sub-headings (### Overview) because substring
matching can't distinguish prose from examples. Replace with a
line-anchored regex match against content that has had fenced code
blocks stripped, so only real top-level headings satisfy the check.

Trigger check: 'Do not use when testing' satisfied the DESCRIPTION_TRIGGER
regex because it contains 'use … when'. Add a negation pattern and reject
descriptions where the only trigger match is negated.

Verified: all 24 skills pass (output unchanged — no current skill has
either bug pattern). Crafted edge cases confirm the fixes catch both
issues. Eval suite green, rank-1 rate unchanged at 86%.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-16 10:47:14 -04:00
Addy OsmaniandGitHub c1974de476 Merge pull request #381 from ZhiyaoWen999/agent/trust-debugging-eval
feat: promote skill eval gates to trusted
2026-07-16 00:22:11 -07:00
Addy OsmaniandGitHub a27e204ac9 Merge pull request #379 from nucliweb/test/skill-lint-extraction
refactor(validate-skills): extract lint rules into a shared lib
2026-07-16 00:22:05 -07:00
ZhiyaoWen999 087033ddf0 feat: support trusted dialogue evals 2026-07-12 22:13:34 +08:00
Joan Leon 495b5a830f refactor(skill-lint): export only functions, keep policy state private
Per review: the policy collections (REQUIRED_SECTIONS, SECTION_EXEMPT_SKILLS,
SKILL_REF_PATTERNS, regexes) were exported by reference, so a consumer could
mutate shared state and change lint results process-wide. Export only the
linting functions; keep the policy collections private. No behavior change
(validator output byte-identical).
2026-07-10 20:05:41 +02:00
Zhiyao 5168535ce4 feat: promote skill eval gates to trusted 2026-07-10 15:29:28 +08:00
Zhiyao 4290228323 test: ratchet deterministic skill eval gates 2026-07-10 14:53:37 +08:00
Joan Leon 94eb14c74b refactor(validate-skills): extract lint rules into scripts/lib/skill-lint.js
Split the skill validation rules out of the validate-skills.js CLI into a
shared, importable scripts/lib/skill-lint.js: a pure lintSkillContent() with
no I/O plus a thin lintSkill() file wrapper. validate-skills.js becomes a thin
CLI over the lib. No behavior change to the validator's output or exit codes;
this only makes the rules unit-testable for a follow-up test battery.
2026-07-10 00:49:00 +02:00
ShiroKSH df8eda8fbe fix: harden eval and command validation 2026-07-09 18:03:46 +03:00
Addy Osmani dd142f1da3 fix(evals): pipe grader prompt via stdin; grant executor tool permissions
Two latent Tier-3 bugs caught in review before the path was ever exercised:

- The grader prompt embeds the full stream-json trace (up to megabytes) and
  was passed as an argv entry, which would fail with E2BIG on any real run.
  It now goes to `claude -p` over stdin; the executor prompt moves to stdin
  for the same reason.
- The executor ran headless with no permission mode, so file edits and
  command runs could be denied, forcing the narrate-instead-of-perform
  failure mode that trace grading exists to catch. It now runs with
  --permission-mode acceptEdits and a pre-approved tool list
  (Read,Glob,Grep,Edit,Write,Bash), documented in the README.
2026-07-06 12:38:26 -07:00
Addy Osmani 194b2099c6 feat(evals): harden Tier 3 and make negatives pairwise routing tests
Per review from @federicobartoli and @nucliweb on #342:

Tier 3 (behavioral):
- Grade the execution trace, not the final output: executor runs with
  --output-format stream-json --verbose so the grader judges tool calls
  and file edits rather than the model's self-reporting.
- Run each eval in a throwaway workspace; files[] fixtures materialize
  from evals/fixtures/ so evals can operate on real code.
- Node-level timeouts on executor and grader calls; grader output parsed
  and shape-validated before writing (raw saved on failure); the trace is
  fenced as untrusted data in the grader prompt.
- All 24 behavioral evals flagged trust_level: "provisional" until they
  gain fixtures; the runner surfaces this and exits nonzero on failed
  expectations.

Tier 2 (deterministic):
- Negative triggers accept an "owner" skill that must outrank this one,
  turning them into pairwise routing tests that cannot pass vacuously;
  37 of 48 negatives now declare owners (the rest are tracked in #351).
- Warn when a case file is below the documented minimums (3 positive /
  2 negative / 1 behavioral); promotion to error tracked in #352.
- Stemmer: cluster trailing y/i ("simplify"/"simplifies").

Baseline holds: 120 checks, 0 errors, 85% trigger rank-1 rate.
2026-07-06 11:36:29 -07:00
Addy Osmani 45e1449138 feat(evals): add a three-tier skill eval framework
There was no way to measure whether skills trigger correctly, stay
distinct, or change agent behavior. This adds evals, aligned with what
the community has converged on, with a deterministic CI tier on top:

- evals/cases/<skill>.json for all 24 skills. The evals[] block uses
  Anthropic skill-creator's evals.json schema verbatim (id, prompt,
  expected_output, expectations[]) so its runner, benchmarks, and eval
  viewer work against our files unmodified. A trigger block (this
  repo's extension) adds positive/negative routing prompts per skill.
- scripts/run-evals.js, zero-dependency runner:
  Tier 2 (CI): trigger evals via stemmed TF-IDF ranking over skill
  descriptions (positive prompts must rank top-k, negative prompts
  must not rank first), catalog collision detection between skill
  descriptions, schema and coverage checks.
  Tier 3 (opt-in): --behavioral <skill> executes each eval through
  headless claude -p and grades the transcript against expectations[]
  (superpowers-style); --dry-run previews without spending tokens.
- CI: run the deterministic tier in the validate-skills job.
- Docs: evals/README.md defines the framework and prior art;
  CONTRIBUTING requires an eval file for new skills (warning-level in
  the runner until in-flight skill PRs clear); CLAUDE.md pointers.

Current baseline: 120 checks pass, 85% trigger rank-1 rate across 72
positive prompts, zero catalog collisions.
2026-07-03 23:46:30 -07:00
An-iddandClaude Opus 4.8 11bfec4d1f feat(scripts): enforce naming + description-trigger rules in skill validator
The validator claims to check skills "against the rules in
docs/skill-anatomy.md", but two rules that doc marks as Required were
never enforced:

- Directory names must be lowercase-hyphen-separated (Naming Conventions).
  Previously only `name === dirName` was checked, so `My_Skill/` passed.
- Descriptions must say *when* to use the skill, not just what it does
  (Required vs Recommended). Formalized in #167 but the validator was
  never updated to match.

Adds both as blocking checks. All 24 existing skills pass, so this is a
non-breaking guardrail. Closes the remaining gap in #233 (frontmatter,
name-match, and section checks already shipped in the original validator).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 10:53:21 +08:00
Addy OsmaniandGitHub 13e43f2310 Merge pull request #270 from nucliweb/ci/validate-commands
ci: validate command descriptions stay in sync across all three tool directories
2026-06-18 20:51:36 -07:00
Joan Leon ca5e33d607 fix(ci): harden validate-commands script
- Support single-quoted TOML description strings (previously silently returned null)
- Wrap file reads in try/catch to produce actionable CI errors instead of raw stack traces
- Remove dead tomlStems variable; declare allTomlStems once and compute allCanonicalStems for an accurate command count in the summary
- Simplify description mismatch output to always show all three values, removing a redundant conditional branch
2026-06-13 11:24:56 +02:00
Joan Leon 5e706d9aa8 ci: validate command descriptions stay in sync across all three tool directories 2026-06-13 10:22:52 +02:00
Swing-G 50d115dc15 fix(scripts): report unexpected fs errors as structured validator output 2026-06-12 11:12:23 +08:00
Dawid Piaskowski 41d15b8d64 Add CI skill validator
- scripts/validate-skills.js: zero-dependency Node.js validator that
  checks every skill for valid frontmatter, description length (≤1024),
  required sections (Overview, When to Use, Common Rationalizations,
  Red Flags, Verification), and dead cross-skill references
- Skills with type:meta or exempt:sections in frontmatter skip section
  checks; applied to using-agent-skills (meta) and idea-refine (legacy
  structure predating the anatomy spec)
- CI: validate-skills job runs before plugin-manifest validation and
  blocks merge on any error; uses Node 20, no npm install required
2026-04-11 12:52:26 +02:00