chore: address Copilot review round 4

- verify:skills:cli — the authoritative validator is now a GUARANTEED step in
  `local:gate` and CI, not a best-effort hand-off. It resolves the CLI itself
  (an installed one at 2.1.233+, else a pinned `npx -y`), so both tiers run the
  same script and cannot drift. `verify:skills` keeps skipping when the CLI is
  absent, which is right for `validate`: fast, offline, no Claude Code required.
- skill-manifest: the 1,536-char listing-entry cap covers `description` +
  `when_to_use` together; checking the description alone passed an over-cap
  entry. `when_to_use` is now parsed, validated and counted, with boundary tests
  at 1,536/1,537.
- verify-skills: report the budget as *this repo's contribution*. The real
  listing budget is shared with bundled skills and the contributor's own
  ~/.claude/skills, none of which is visible from here, so the number was
  claiming more than it measured.
- skill-eval: a negative case now means "no skill OF THIS REPO'S fired". It
  failed on any Skill invocation, so a contributor with an unrelated global
  skill got a false failure about their environment rather than these skills.
- docs/architecture + local-dev: the Node backend runner gets its
  `@inspector/core` alias from `clients/web/tsup.runner.config.ts`, not from
  Vite. The old text sent runner work to the wrong config.
- local-dev: the tarball does not ship "only each client's build/" — the
  allowlist also carries `clients/web/dist`, `clients/web/static` and the
  install helper. States the invariant that actually matters instead.
- issue-triage: the test for needing triage is "no board card". Adding "and no
  milestone" would skip the approved-but-unboarded case the same section then
  handles. Also corrected the `$M` note: the lookup is `--state all`, so closed
  issues DO have entries — `isopen` is about the invariants, not the lookup.
- issue-create: replaced "all five" with a per-version table. Steps 3 and 6
  (milestone, Priority) do not exist for v1, so the old list opened with a rule
  the same skill later tells you to violate.

Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
cliffhall 2026-08-29 01:47:43 -04:00
commit d05e76d470

View file

@ -219,3 +219,36 @@ test("compareVersions orders the plugin-validate floor correctly", () => {
assert.ok(compareVersions([3], PLUGIN_VALIDATE_MIN_VERSION) > 0);
assert.ok(compareVersions([1, 9, 999], PLUGIN_VALIDATE_MIN_VERSION) < 0);
});
test("the listing-entry cap covers description AND when_to_use together", () => {
// The cap is over the combined entry, so checking `description` alone would
// pass an over-cap listing entry.
const under = fm(
`name: x\ndescription: ${"a".repeat(1000)}\nwhen_to_use: ${"b".repeat(536)}\ndisable-model-invocation: true`,
);
assert.deepEqual(parseSkill("x", under).errors, []);
const over = fm(
`name: x\ndescription: ${"a".repeat(1000)}\nwhen_to_use: ${"b".repeat(537)}\ndisable-model-invocation: true`,
);
assert.match(parseSkill("x", over).errors.join(), /caps a listing entry/);
assert.match(
parseSkill(
"x",
fm(
"name: x\ndescription: d\nwhen_to_use: 7\ndisable-model-invocation: true",
),
).errors.join(),
/when_to_use. must be a string/,
);
});
test("listingCost counts when_to_use too", () => {
assert.equal(
listingCost([
{ name: "aa", description: "bbb", whenToUse: "cc", modelInvoked: true },
]),
7,
);
});