From 149d564f6a0aa6be71a65cd3c56befde33903aef Mon Sep 17 00:00:00 2001 From: Defame1297 Date: Sat, 8 Aug 2026 20:42:15 +0000 Subject: [PATCH] fix(lint): make the Vale gate actually gate, drop VagueQualifier MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Round-3 review of PR #85 found the "enforcing" pre-commit hook enforced nothing. Vale's exit code keys on error-level alerts alone: five of the six rules were level: warning, so they exited 0, and pre-commit hides output from a passing hook — the alerts were invisible and blocked nothing. ADR-0013 rejected a report-only trial tier and then shipped one by accident. Flatten every rule to level: error. Vale's own exit code is then correct, so the hook entry drops to a bare vale-wrap.sh call and the graded error->FAIL / warning->SUGGESTION mapping disappears from both audit skills: every alert is a FAIL, in the gate and the audit alike. No ignorable tier, matching shellcheck, the test suite and conventional-pre-commit. Delete Kyberforge.VagueQualifier. Measured against the 41 skill/agent files as they stood before the rule ever ran: 2 hits. One marginal ("very different" -> "fundamentally different"), one an unfixable false positive — caveman/SKILL.md quotes "of course" as an example of filler, a mention not a use — which forced the only Vale suppression comments in the repo. Those four lines go with it; two of them were dead anyway, suppressing a frontmatter-scoped rule on a body line. Held-out prose (273 files) fired 15 times, 9 inside out-of-scope research examples and the rest one word in two idioms in a single doc. SentenceOpenerThereIs survives: 22 held-out hits, both in-corpus hits clean rewrites, zero suppressions. Widen .vale.ini's globs to [**/SKILL.md], [**/agents/*.md] and [**/*.agent.md]. The plugins/*/-prefixed globs scoped nothing — Vale's * crosses /, so they already matched docs/research/examples/**/agents/*.md and assets/templates/SKILL.md, the two paths CONTEXT.md claimed they excluded. Scoping is and was the hook's files: regex. The old globs also hid a silent false negative: a skill outside plugins/ matched no section, so Vale reported 0 files and exited 0, which both audits read as clean. They now treat a 0-file run as NOT RUN and fall back to full judgment. Also: - vale-wrap.sh resolves relative --config values and file arguments against the caller's cwd, as vale does, instead of the repo root, which hard-errored from a subdirectory and silently skipped flattening for file args that did not resolve from the root. Absolute paths inside the cwd are relativized so reports cite resolvable paths, not scratch ones. - vale-run's exit-code model was documented backwards ("exits non-zero whenever it finds an alert at or above MinAlertLevel") and would have led anyone following it to build a gate that passes everything. Its Markdown suppression syntax was MDX-only and does not suppress in .md; corrected in the skill and its troubleshooting reference, with backtick/fence exemption documented as the first resort. - skill-size-check.sh fails only above 500 lines, agreeing with skill-audit's validate.sh <= 500 pass. - ADR-0013 and CONTEXT.md amended to match, recording why graded severities cannot gate. Verified: 9 test scripts / 15 vale-wrap cases pass; vale-audit-prefilter, skill-size-check and shellcheck pass --all-files; check-manifests and claude plugin validate --strict clean. New tests fail against the old script (3 of them) and pass against the new one. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01MCQ648fLSFXPHGZdQ8gn58 --- .pre-commit-config.yaml | 2 +- .vale.ini | 7 +- CONTEXT.md | 6 +- ...013-vale-harness-scope-and-rule-sources.md | 40 +++++-- plugins/bin/skills/caveman/SKILL.md | 7 +- .../kyberforge/skills/agent-audit/SKILL.md | 6 +- .../kyberforge/skills/skill-audit/SKILL.md | 6 +- plugins/lint/skills/vale-run/SKILL.md | 17 +-- .../vale-run/references/troubleshooting.md | 19 ++- scripts/skill-size-check.sh | 21 ++-- scripts/vale-wrap.sh | 107 ++++++++++++----- styles/Kyberforge/PaddingPhrase.yml | 2 +- styles/Kyberforge/SentenceOpenerThereIs.yml | 2 +- styles/Kyberforge/VagueQualifier.yml | 19 --- styles/Kyberforge/VagueWording.yml | 2 +- styles/KyberforgeCopilot/ProactivePhrase.yml | 2 +- tests/test-skill-size-check.sh | 32 +++--- tests/test-vale-wrap.sh | 108 ++++++++++++++---- 18 files changed, 269 insertions(+), 136 deletions(-) delete mode 100644 styles/Kyberforge/VagueQualifier.yml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ed9a129..ad1a9d6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -111,7 +111,7 @@ repos: stages: ['pre-commit'] name: Vale audit prefilter description: Run Vale against skill/agent markdown files as a deterministic prefilter for skill-audit/agent-audit - entry: scripts/vale-wrap.sh --config .vale.ini --minAlertLevel=warning + entry: scripts/vale-wrap.sh --config .vale.ini language: script files: '^plugins/[^/]+/(skills/[^/]+/SKILL\.md|agents/[^/]+\.md)$' pass_filenames: true diff --git a/.vale.ini b/.vale.ini index c0d0410..f4a9999 100644 --- a/.vale.ini +++ b/.vale.ini @@ -1,11 +1,10 @@ StylesPath = styles -MinAlertLevel = suggestion -[plugins/*/skills/*/SKILL.md] +[**/SKILL.md] BasedOnStyles = Kyberforge -[plugins/*/agents/*.md] +[**/agents/*.md] BasedOnStyles = Kyberforge -[plugins/*/agents/*.agent.md] +[**/*.agent.md] BasedOnStyles = Kyberforge, KyberforgeCopilot diff --git a/CONTEXT.md b/CONTEXT.md index 142f18b..78ae023 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -70,11 +70,11 @@ A companion skill (`core` plugin) that detects a target repo's provider-specific A standalone, repo-agnostic plugin (`plugins/lint/`) for configuring and running linters — not scoped to kyberforge's own meta-tooling. First linter is Vale (prose style linting), split into two skills per the git/gitea per-concern pattern: `vale-config` (setup — `.vale.ini`, `StylesPath`, styles) and `vale-run` (invoke Vale, interpret/report findings). A `lint-runner` agent composes these for isolated-context lint sweeps; it is report-only (no `Edit` tool) — it flags findings, it does not rewrite prose. Vale's research docs (`docs/research/docs/vale/`) moved from `plugins/kyberforge/` to `plugins/lint/` to keep the provenance chain same-plugin. ### Vale audit prefilter (skill-audit / agent-audit) -Wiring Vale as a deterministic prefilter for `skill-audit`/`agent-audit`'s Description dimension (ADR motivation: issue #84) is repo-specific, not part of the generic `lint` plugin, so its config lives at the repo root rather than inside `plugins/lint/`: `.vale.ini` plus a custom `Kyberforge` style (`styles/Kyberforge/`) covering description-opener banning ("This skill/agent..."), vague-capability wording ("helps with", "utilize", ...), and generic "see references/ for details" padding — and a `KyberforgeCopilot` style (`styles/KyberforgeCopilot/`) scoped only to `.agent.md` files for the Copilot-only "Use proactively has no effect" check. `error` alerts map to FAIL, `warning`/`suggestion` map to SUGGESTION. Vale covers the pattern-matchable sub-checks named in issue #84 (imperative opener, vague filler, `Use proactively`, generic reference-pointer padding) plus, per ADR-0013, two body-wide prose-pattern checks (vague-qualifier filler, "There is/are" sentence openers) — everything else about body discipline (defaults-vs-menus, why-rationale, non-pattern-matchable judgment calls), near-miss exclusion strength, and control calibration stays LLM judgment. +Wiring Vale as a deterministic prefilter for `skill-audit`/`agent-audit`'s Description dimension (ADR motivation: issue #84) is repo-specific, not part of the generic `lint` plugin, so its config lives at the repo root rather than inside `plugins/lint/`: `.vale.ini` plus a custom `Kyberforge` style (`styles/Kyberforge/`) covering description-opener banning ("This skill/agent..."), vague-capability wording ("helps with", "utilize", ...), and generic "see references/ for details" padding — and a `KyberforgeCopilot` style (`styles/KyberforgeCopilot/`) scoped only to `.agent.md` files for the Copilot-only "Use proactively has no effect" check. Every rule is `level: error` and every alert is a FAIL — no ignorable tier, same as shellcheck, the test suite, and conventional-pre-commit. Graded severities do not work here: Vale's exit code keys on `error` alerts alone, so `warning`/`suggestion` rules exit 0 and pre-commit swallows the output of a passing hook, leaving them invisible and blocking nothing. `MinAlertLevel` and `--minAlertLevel` are correspondingly absent from `.vale.ini` and the hook, being no-ops under this model. Vale covers the pattern-matchable sub-checks named in issue #84 (imperative opener, vague filler, `Use proactively`, generic reference-pointer padding) plus, per ADR-0013, one body-wide prose-pattern check ("There is/are" sentence openers) — everything else about body discipline (defaults-vs-menus, why-rationale, non-pattern-matchable judgment calls), near-miss exclusion strength, and control calibration stays LLM judgment. -Both skills' Step 1, and the `vale-audit-prefilter` pre-commit hook, call `scripts/vale-wrap.sh` rather than `vale` directly — a workaround for a confirmed Vale 3.15.2 limitation (see `vale-config`'s Gotchas): `text.frontmatter.description` silently stops matching once the description is a YAML block scalar (`>`/`|`) spanning 2+ physical lines, which is how most skills/agents in this repo write it. The wrapper flattens the description to one physical line in a scratch copy (padding with blank lines so every other line number is unchanged) before handing off to real `vale`; single-line descriptions pass through untouched. `tests/test-vale-wrap.sh` regression-tests this. Both call sites still scope every invocation to the specific file(s) being audited, never a repo-wide sweep — Vale's glob matching crosses directory boundaries (`plugins/*/agents/*.md` matches nested `docs/research/examples/**/agents/*.md` too), so scoping is what keeps research-example files out of the audit's lint pass. The pre-commit hook's own glob is tightened to `^plugins/[^/]+/(skills/[^/]+/SKILL\.md|agents/[^/]+\.md)$` (single-segment, not `.*`) for the same reason, since pre-commit invokes it automatically against whatever staged files match rather than a manually-scoped target. +Both skills' Step 1, and the `vale-audit-prefilter` pre-commit hook, call `scripts/vale-wrap.sh` rather than `vale` directly — a workaround for a confirmed Vale 3.15.2 limitation (see `vale-config`'s Gotchas): `text.frontmatter.description` silently stops matching once the description is a YAML block scalar (`>`/`|`) spanning 2+ physical lines, which is how most skills/agents in this repo write it. The wrapper flattens the description to one physical line in a scratch copy (padding with blank lines so every other line number is unchanged) before handing off to real `vale`; single-line descriptions pass through untouched; a relative `--config` path resolves against the caller's cwd, matching bare `vale`, not against the repo root. `tests/test-vale-wrap.sh` regression-tests this. `.vale.ini`'s section globs are path-agnostic (`[**/SKILL.md]`, `[**/agents/*.md]`, `[**/*.agent.md]`) and do no scoping: Vale's `*` crosses `/`, so the older `plugins/*/`-prefixed globs already matched `plugins/*/docs/research/examples/**/agents/*.md` and `plugins/*/skills/*/assets/templates/SKILL.md`. Scoping comes from the pre-commit hook's `files:` regex, `^plugins/[^/]+/(skills/[^/]+/SKILL\.md|agents/[^/]+\.md)$` (single-segment, not `.*`, since pre-commit invokes it automatically against whatever staged files match rather than a manually-scoped target), and from the audit skills passing one explicit file per invocation. The path-agnostic globs also close a silent false negative: a skill outside `plugins/` (e.g. project-scope `.claude/skills/foo/SKILL.md`) matched no section, so Vale reported 0 files and exited 0 — which the audits read as clean. Both audits now treat a 0-file Vale run as NOT RUN and fall back to full LLM judgment. -This scope expands per ADR-0013: cherry-picked low-noise `write-good`/`alex` rules landed in `styles/Kyberforge` as two new rule files, `Kyberforge.VagueQualifier` and `Kyberforge.SentenceOpenerThereIs`, plus a new sibling pre-commit hook, `skill-size-check` (`scripts/skill-size-check.sh`), enforcing agentskills.io's 500-line/5,000-token `SKILL.md` ceiling — scoped to `^plugins/[^/]+/skills/[^/]+/SKILL\.md$` only, same as `vale-audit-prefilter`, so it never lints `docs/research/examples/` reference skills. File scope (`SKILL.md` + agent files) and enforcement model (rules land directly in `styles/Kyberforge`, blocking immediately, no trial tier) stay unchanged; governance.md/CONTROLS.md were evaluated and excluded as rule sources (nothing prose-pattern-matchable to mine). +This scope expands per ADR-0013: one cherry-picked low-noise `write-good`/`alex` rule landed in `styles/Kyberforge`, `Kyberforge.SentenceOpenerThereIs` (22 held-out hits, both in-corpus hits clean rewrites, zero suppressions). A second, `Kyberforge.VagueQualifier`, was cherry-picked and then deleted: 2 hits across the 41 skill/agent files, one marginal and one an unfixable false positive (`caveman/SKILL.md` quotes `of course` as an example of filler — a mention, not a use) that forced the repo's only Vale suppression comments. Also new is a sibling pre-commit hook, `skill-size-check` (`scripts/skill-size-check.sh`), enforcing agentskills.io's 500-line/5,000-token `SKILL.md` ceiling — failing only above 500 lines, matching `skill-audit/scripts/validate.sh`'s `<= 500` pass — scoped to `^plugins/[^/]+/skills/[^/]+/SKILL\.md$` only, same as `vale-audit-prefilter`, so it never lints `docs/research/examples/` reference skills. File scope (`SKILL.md` + agent files) and enforcement model (rules land directly in `styles/Kyberforge`, blocking immediately, no trial tier) stay unchanged; governance.md/CONTROLS.md were evaluated and excluded as rule sources (nothing prose-pattern-matchable to mine). House convention: banned phrasing that must be mentioned rather than used goes in backticks or a fenced code block — Vale skips code spans and fences, so no suppression is needed; inline `` (HTML-comment form; the MDX `{/* */}` form does not work in plain Markdown) is the fallback only where backticking is impossible. ### LESSONS.md Long-loop feedback log for patterns observed across sessions. Three or more entries on the same pattern graduate to the relevant standing file (e.g. a coding convention, a governance rule). Updated by the session-handoff skill or directly by the human. Lives at the repo root. diff --git a/docs/adr/0013-vale-harness-scope-and-rule-sources.md b/docs/adr/0013-vale-harness-scope-and-rule-sources.md index 3ed267e..2227a9e 100644 --- a/docs/adr/0013-vale-harness-scope-and-rule-sources.md +++ b/docs/adr/0013-vale-harness-scope-and-rule-sources.md @@ -9,8 +9,8 @@ deferred PR #85 review item to broaden that coverage, retroactively captures #84 (since it was never recorded as a decision in its own right), and layers the expansion on top without reversing or weakening the original four rules. -**File scope stays the same.** `SKILL.md` plus agent files (`plugins/*/agents/*.md`, -`plugins/*/agents/*.agent.md`) only — matching the existing prefilter's globs. Skill-level +**File scope stays the same.** `SKILL.md` plus agent files (`**/agents/*.md`, +`**/*.agent.md`) only — matching the existing prefilter's globs. Skill-level `README.md` files and `plugin.json` manifests are not added: README.md files are navigational, not spec-governed content, and `plugin.json` is JSON, not prose Vale can meaningfully lint. @@ -51,7 +51,13 @@ length ceiling, not a text pattern, so it isn't a Vale rule — it becomes a new and pre-commit hook, sibling to the existing `skill-frontmatter` hook. **Rules land directly in `styles/Kyberforge`, enforcing immediately.** No trial/report-only tier -is introduced (see Considered Options). The implementation pass finalizes the cherry-picked +is introduced (see Considered Options). "Enforcing immediately" holds only because every rule in +both styles is `level: error`: Vale's exit code keys on `error`-level alerts alone, so a +`warning`- or `suggestion`-level rule prints an alert and still exits 0, and pre-commit suppresses +output from hooks that pass — such a rule is invisible and blocks nothing. Every Vale alert is +therefore a FAIL, in the audit skills and in the blocking pre-commit hook alike, with no ignorable +tier; that matches every other gate in this repo (shellcheck, the test suite, +conventional-pre-commit). The implementation pass finalizes the cherry-picked `write-good`/`alex` rules and any new spec-derived rule wording, runs the full set against the existing SKILL.md/agent-file corpus, fixes any resulting violations across that corpus, and lands the rule changes and the corpus fixes as one atomic commit — the same enforcement model as the @@ -68,14 +74,29 @@ under that directory automatically — there's no partial/opt-in application wit rule dropped straight into `styles/Kyberforge` goes live in the blocking pre-commit hook immediately. Rejected in favor of finalizing rules directly and fixing violations via subagent before committing: simpler, no new trial-config machinery to build or maintain — at the cost of no -standing report-only tier for future candidate rules. +standing report-only tier for future candidate rules. Note that the first implementation shipped +graded severities (`error`/`warning`/`suggestion`) and thereby recreated the rejected option by +accident: the five non-`error` rules never affected an exit code and never surfaced output through +a passing pre-commit hook, so they were a report-only tier that reported to nobody. Flattening +every rule to `level: error` is what actually implements this decision. ## Consequences -- `styles/Kyberforge/` gained two new rule files, cherry-picked from `write-good`/`alex` as - low-noise against this repo's corpus: `VagueQualifier.yml` and `SentenceOpenerThereIs.yml`. +- `styles/Kyberforge/` gained one new rule file, cherry-picked from `write-good`/`alex` as + low-noise against this repo's corpus: `SentenceOpenerThereIs.yml` (22 hits across 273 held-out + markdown files; both in-corpus hits were clean rewrites, needing no suppression). +- A second candidate, `VagueQualifier.yml`, was cherry-picked and then dropped. Against the 41 + skill/agent files it hit twice: one marginal real finding (`prototype/SKILL.md`, "very different" + → "fundamentally different") and one false positive (`caveman/SKILL.md`, which *quotes* `of + course` as an example of filler — a mention, not a use) that no rewrite could clear, forcing the + repo's only Vale suppression comments. Of its 15 held-out hits, 9 were in `docs/research/examples/` + (out-of-scope upstream material) and the remaining 6 were the word "very" in two idioms in a + single research doc, each already adjacent to the hard number carrying the fact. One marginal + catch does not pay for a permanent suppression, so the rule is deleted and this ADR's + "cherry-picked rules" is one rule, not two. - A new pre-commit hook, `skill-size-check` (`scripts/skill-size-check.sh`), enforces the - 500-line/5,000-token `SKILL.md` ceiling, sibling to `skill-frontmatter`. + 500-line/5,000-token `SKILL.md` ceiling, sibling to `skill-frontmatter`. It fails only *above* + 500 lines, matching `skill-audit/scripts/validate.sh`'s long-standing `<= 500` pass. - `styles/KyberforgeTrial/` and `.vale.trial.ini` were deliberately not created — noted here so a future reader doesn't wonder if a trial tier was forgotten. - The styles-portability question — whether `styles/` and `.vale.ini` should move into @@ -87,7 +108,8 @@ standing report-only tier for future candidate rules. not silently forgotten. **What this ADR's implementation pass did:** synced and trialed `write-good`/`alex` against the -existing SKILL.md/agent-file corpus, cherry-picked the two low-noise rules above into +existing SKILL.md/agent-file corpus, cherry-picked the one low-noise rule above into `styles/Kyberforge`, wrote `scripts/skill-size-check.sh` and its pre-commit hook, fixed the resulting corpus violations, and landed the rule changes and corpus fixes as one atomic commit — -matching the enforcement model described above (no partial or opt-in state). +matching the enforcement model described above (no partial or opt-in state), with every rule at +`level: error` so that model is real rather than nominal. diff --git a/plugins/bin/skills/caveman/SKILL.md b/plugins/bin/skills/caveman/SKILL.md index 72bcd66..85770a3 100644 --- a/plugins/bin/skills/caveman/SKILL.md +++ b/plugins/bin/skills/caveman/SKILL.md @@ -15,12 +15,7 @@ ACTIVE EVERY RESPONSE once triggered. No revert after many turns. No filler drif ## Rules - - -Drop: articles (a/an/the), filler (just/really/basically/actually/simply), pleasantries (sure/certainly/of course/happy to), hedging. - - -Fragments OK. Short synonyms (big not extensive, fix not "implement a solution for"). Abbreviate common terms (DB/auth/config/req/res/fn/impl). Strip conjunctions. Use arrows for causality (X -> Y). One word when one word enough. +Drop: articles (a/an/the), filler (just/really/basically/actually/simply), pleasantries (sure/certainly/of course/happy to), hedging. Fragments OK. Short synonyms (big not extensive, fix not "implement a solution for"). Abbreviate common terms (DB/auth/config/req/res/fn/impl). Strip conjunctions. Use arrows for causality (X -> Y). One word when one word enough. Technical terms stay exact. Code blocks unchanged. Errors quoted exact. diff --git a/plugins/kyberforge/skills/agent-audit/SKILL.md b/plugins/kyberforge/skills/agent-audit/SKILL.md index e2e9714..f7ba49d 100644 --- a/plugins/kyberforge/skills/agent-audit/SKILL.md +++ b/plugins/kyberforge/skills/agent-audit/SKILL.md @@ -41,7 +41,7 @@ bash scripts/validate-provenance.sh The script accepts either the CC file or the Copilot file. It detects provider from extension, derives the counterpart, and runs all structural checks. Note FAILs and SUGGESTIONs for the `### Structure` and `### Provider safety` report dimensions. Findings about missing fields, bad name format, empty body, or missing frontmatter → `### Structure`. Findings about CC-only fields in a Copilot file, Copilot-only fields in a CC file, plugin-silently-ignored fields, body length, or subagent-unavailable tools → `### Provider safety`. A missing counterpart file → `### Pair consistency`. -`vale-wrap.sh` resolves its own path and `.vale.ini` via `git rev-parse --show-toplevel`, so it runs correctly regardless of the caller's cwd. Run it against both files of the pair (not just the one passed in). `Kyberforge` applies to both files; `KyberforgeCopilot` applies to the `.agent.md` file only, since its one rule (`Use proactively`) flags CC-specific phrasing that's meaningless in a Copilot description — there's nothing to flag in the CC file, so it isn't scoped there. Map `error` → `FAIL` and `warning`/`suggestion` → `SUGGESTION` in the `### Description` / `### Body` dimensions, citing the rule ID (e.g. `KyberforgeCopilot.ProactivePhrase`). Skip and fall back to Step 2 judgment if vale or `.vale.ini` is unavailable. +`vale-wrap.sh` resolves its own path and `.vale.ini` via `git rev-parse --show-toplevel`; pass the absolute paths shown above so the invocation holds from any cwd. Run it against both files of the pair (not just the one passed in). `Kyberforge` applies to both files; `KyberforgeCopilot` applies to the `.agent.md` file only, since its one rule (`Use proactively`) flags CC-specific phrasing that's meaningless in a Copilot description — there's nothing to flag in the CC file, so it isn't scoped there. Every Vale alert is a `FAIL` — all rules are graded `error` — so report each one in the `### Description` / `### Body` dimensions citing its rule ID (e.g. `KyberforgeCopilot.ProactivePhrase`). Skip and fall back to Step 2 judgment if vale or `.vale.ini` is unavailable. If Vale reports `0 files` scanned, treat the pass as NOT RUN — not as clean — and fall back to full Step 2 judgment for the dimensions it would have covered. `validate-provenance.sh` validates the provenance chain between the agent pair's `source_keys` and the plugin-scoped `sources.md` (plugin root — see ADR-0010). It exits 0 silently for non-plugin-scope agents and when no provenance data exists. Note FAILs from this script for the `### Provenance` dimension — surface them verbatim with Why and Fix. @@ -53,7 +53,7 @@ Read both agent files. Work through each dimension internally. Collect findings **Description (both files):** - Action-verb opening: description starts with a verb ("Reviews...", "Analyzes...", "Generates...") — FAIL if absent. Vale's `Kyberforge.DescriptionOpener` alert flags the specific known-bad "This agent..." opener directly; verifying an arbitrary opening word is genuinely a strong verb still requires judgment. -- Specificity: is the trigger condition stated precisely? — SUGGESTION if vague. Vale's `Kyberforge.VagueWording` alert covers known filler ("helps with", "utilize", ...) directly; report those without re-deriving by judgment. +- Specificity: is the trigger condition stated precisely? — SUGGESTION if vague. Vale's `Kyberforge.VagueWording` alert covers known filler ("helps with", "utilize", ...) directly; report those as FAILs without re-deriving by judgment. - `Use proactively` in a Copilot description: Vale's `KyberforgeCopilot.ProactivePhrase` alert (Copilot file only) flags this directly — report it without re-deriving by judgment. If a description finding is borderline, read `references/description-quality.md`. @@ -62,7 +62,7 @@ If a description finding is borderline, read `references/description-quality.md` - Direct role instruction: system prompt opens with `You are a [role]. When invoked, [action].` — SUGGESTION if absent - One job per agent: system prompt describes a single bounded task — SUGGESTION if scope appears unbounded - Generic, non-specific reference pointers to the `references/` directory: Vale's `Kyberforge.PaddingPhrase` alert flags this directly — report it without re-deriving by judgment -- Vague filler wording and sentences that open with "There is"/"There are": Vale's `Kyberforge.VagueQualifier` and `Kyberforge.SentenceOpenerThereIs` alerts flag this directly — report them without re-deriving by judgment +- Sentences that open with "There is"/"There are": Vale's `Kyberforge.SentenceOpenerThereIs` alert flags this directly — report it without re-deriving by judgment **Body/Frontmatter comments:** - Inspect each comment block in the YAML frontmatter. For each comment, apply: *"Would the agent get this wrong without this comment?"* Flag any that answer "no" as padding. diff --git a/plugins/kyberforge/skills/skill-audit/SKILL.md b/plugins/kyberforge/skills/skill-audit/SKILL.md index 3c82a51..d05f681 100644 --- a/plugins/kyberforge/skills/skill-audit/SKILL.md +++ b/plugins/kyberforge/skills/skill-audit/SKILL.md @@ -41,7 +41,7 @@ Note any structural FAILs — they will appear in the report as a `### Structure Note any Provenance FAILs and INFO findings from `validate-provenance.sh` — they surface in the report as a `### Provenance` dimension (separate from `### Structure`). The script embeds full FAIL/INFO format with Why and Fix per finding; surface them verbatim. -`vale-wrap.sh` resolves its own path and `.vale.ini` via `git rev-parse --show-toplevel`, so it runs correctly regardless of the caller's cwd, using `.vale.ini`'s `Kyberforge` style — a deterministic prefilter for a subset of the Description/Patterns dimensions below, not a replacement for Step 3. Map `error` → `FAIL` and `warning`/`suggestion` → `SUGGESTION` in those dimensions, citing the rule ID (e.g. `Kyberforge.DescriptionOpener`). Skip and fall back to Step 3 judgment if vale or `.vale.ini` is unavailable. +`vale-wrap.sh` resolves its own path and `.vale.ini` via `git rev-parse --show-toplevel`; pass the absolute paths shown above so the invocation holds from any cwd. It applies `.vale.ini`'s `Kyberforge` style — a deterministic prefilter for a subset of the Description/Patterns/Body dimensions below, not a replacement for Step 3. Every Vale alert is a `FAIL` — all rules are graded `error` — so report each one citing its rule ID (e.g. `Kyberforge.DescriptionOpener`). Skip and fall back to Step 3 judgment if vale or `.vale.ini` is unavailable. If Vale reports `0 files` scanned, treat the pass as NOT RUN — not as clean — and fall back to full Step 3 judgment for the dimensions it would have covered. ## Step 2 — Read all skill files @@ -53,7 +53,7 @@ Work through each dimension internally. Collect findings only; report them in St ### Description -Vale's `Kyberforge.DescriptionOpener` (FAIL — "This skill..." openers) and `Kyberforge.VagueWording` (SUGGESTION — filler like "helps with", "utilize") alerts from Step 1 cover imperative phrasing and known vague-wording filler directly; report them as findings without re-deriving by judgment. The rest is still a judgment call: +Vale's `Kyberforge.DescriptionOpener` ("This skill..." openers) and `Kyberforge.VagueWording` (filler like "helps with", "utilize") alerts from Step 1 — both FAILs — cover imperative phrasing and known vague-wording filler directly; report them as findings without re-deriving by judgment. The rest is still a judgment call: - **Specificity beyond the filler blocklist**: are capabilities stated precisely ("parses OpenAPI specs") or genuinely vaguely ("handles files")? - **Indirect triggers**: does it cover cases where the user doesn't name the domain directly? @@ -70,7 +70,7 @@ For each sentence in the body, apply: *"Would the agent get this wrong without t - **Why rationale**: include/exclude rules explain why, not just what - **Control calibration**: prescriptive for fragile or critical sequences (e.g. a script invocation where flag order or exact arguments must not change); flexible where multiple approaches are valid -Vale's `Kyberforge.VagueQualifier` (SUGGESTION — vague filler like "clearly", "obviously") and `Kyberforge.SentenceOpenerThereIs` (SUGGESTION — sentences starting with "There is"/"There are") alerts from Step 1 cover pattern-matchable body-wide filler directly; report them as findings without re-deriving by judgment. +Vale's `Kyberforge.SentenceOpenerThereIs` alert from Step 1 (FAIL — sentences starting with "There is"/"There are") covers pattern-matchable body-wide filler directly; report it as a finding without re-deriving by judgment. If uncertain whether a sentence is padding or whether a control decision is correctly calibrated, read `references/body-discipline.md`. diff --git a/plugins/lint/skills/vale-run/SKILL.md b/plugins/lint/skills/vale-run/SKILL.md index c1f4915..11f443a 100644 --- a/plugins/lint/skills/vale-run/SKILL.md +++ b/plugins/lint/skills/vale-run/SKILL.md @@ -19,9 +19,9 @@ metadata: ## Gotchas -- Vale exits non-zero whenever it finds an alert at or above `MinAlertLevel` — that's what makes it usable as a CI gate, not a sign the invocation failed. Read the output before concluding the command errored. +- Vale's exit code is driven by `error`-level alerts only. `warning` and `suggestion` alerts are reported but still exit `0`. `MinAlertLevel` and `--minAlertLevel` control display, never the exit code — no flag makes warnings fail. A rule that must gate CI or a commit hook has to be `level: error`. This is the single most common way a Vale gate silently passes everything. - `vale ls-config` prints the fully-resolved, currently active configuration as JSON — the fastest way to check why a rule "isn't applying" is what's actually active, not what's written in `.vale.ini`. -- Inline suppression syntax is format-specific: Markdown/MDX uses `{/* vale off */}` / `{/* vale on */}`, Org mode uses `# vale off` / `# vale on`. Don't assume one syntax works across formats. +- Inline suppression syntax is format-specific: Markdown uses HTML comments `` / ``, MDX uses `{/* vale off */}` / `{/* vale on */}`, Org mode uses `# vale off` / `# vale on`. The MDX form does nothing in a plain `.md` file — the alert still fires. Don't assume one syntax works across formats. - Before calling the `vale` binary directly, check whether the target repo documents its own wrapper script for Vale (look in its README, CONTRIBUTING docs, pre-commit config, or a `scripts/` directory). Some projects wrap `vale` to work around real bugs — e.g. a scope that silently stops matching multi-line YAML block-scalar frontmatter fields — and calling bare `vale` in a repo that has such a wrapper silently skips whatever the wrapper works around. If a wrapper is documented, invoke it with the same arguments instead of calling `vale` directly; otherwise fall back to the default below. ## Running vale @@ -37,8 +37,8 @@ Key flags: | Flag | Purpose | |---|---| | `--output=