Addresses PR #85's outstanding review items after grilling the open
questions against ADR-0013/CONTEXT.md/ADR-0010:
Blocking fixes:
- vale-wrap.sh: replace json.dumps() escaping (which silently defeated
Vale's frontmatter scope on any description containing a quote,
backslash, or non-ASCII char — ~58% of the corpus) with a single-quoted
YAML scalar, substituting a Unicode right single quote for embedded
apostrophes rather than '' doubling (Vale's frontmatter scanner isn't a
full YAML parser and silently truncates on '' too).
- vale-wrap.sh: fix a blank-line-inside-a-folded-description truncation
bug via indentation-based, blank-line-tolerant body capture; narrow
flattening to `>`-style scalars only (`|` already works unflattened).
- skill-audit/agent-audit Step 1: make the vale-wrap.sh invocation
cwd-independent via git rev-parse --show-toplevel, fixing a bug where
no single cwd satisfied all three Step 1 commands.
- styles/Kyberforge/VagueQualifier.yml: prune 17 tokens verified
false-positive-dominated on this repo's own voice via a real corpus
sweep (obvious, clearly, usually, several, simple, easy, completely,
simply, tiny, etc.), keep 13 with real or unattested noise. Revert the
28 prose "fixes" those tokens drove across 14 skill files back to their
original, correct wording, including a functional regression to
caveman/SKILL.md's own filler-word list (a mention, not a use) — now
guarded with vale-off comments against recurrence.
Gaps:
- --minAlertLevel=warning on the pre-commit hook and Step 1 invocation
so warning-level rules actually surface, without collapsing the
FAIL/SUGGESTION severity mapping skill-audit/agent-audit rely on.
- vale-wrap.sh: fix --config=<path> equals-form, absolute-path silent
no-op, and a zero-file-argument stdin hang.
- Route vale-run and lint-runner through a documented wrapper script
when a target repo has one, instead of unconditionally recommending
bare `vale`.
- Wire Kyberforge.VagueQualifier/SentenceOpenerThereIs into skill-audit/
agent-audit's dimension-mapping prose (Body discipline).
- Add plugins/lint/sources.md provenance for lint-runner (ADR-0010).
- Sync both marketplace.json lint-entry descriptions with plugin.json.
- Retune skill-size-check.sh's MAX_WORDS 5000->2900 (measured ~1.6-1.7
tokens/word on this repo's corpus, the old value gated at ~8,500
tokens against a stated 5,000 ceiling); fix the >/>= line-count
boundary and wc -l undercount on files with no trailing newline.
- Document the vale binary as a Setup prerequisite in AGENTS.md.
- Fix SentenceOpenerThereIs's dead regex alternative and add a real
sentence-start anchor/scope.
- Fix a stale docs/research/docs/vale/ index pointer in kyberforge's
docs README (moved to plugins/lint/ in e1a5403).
- Rewrite ADR-0013's Consequences section past-tense to describe what
actually landed, and record the styles-portability limitation
(repo-root placement stays intentional; deferred to a separate
session per this PR's review).
Test coverage: 9 new vale-wrap.sh fixtures (quotes, backslash/unicode,
blank-line paragraphs, --config= form, zero-arg/absolute-path handling,
literal-block no-regression) and boundary-pair tests for
skill-size-check.sh's line/word ceilings.
bash tests/run-tests.sh: 9 scripts + 125 bats assertions, all passing.
scripts/check-manifests.sh and claude plugin validate --strict: clean.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MCQ648fLSFXPHGZdQ8gn58
4.4 KiB
name, description, metadata
| name | description | metadata | |||||||
|---|---|---|---|---|---|---|---|---|---|
| vale-run | Use when running Vale (a prose/style linter) against files or directories in an already-configured project — one that already has a .vale.ini — and interpreting or reporting its results: choosing an output format for humans vs. CI, filtering by severity, handling Vale's exit codes in scripts, or resolving common runtime issues like false positives and unexpected CI failures. Use even if the user doesn't say "vale" explicitly, e.g. "lint the docs", "check prose style", "run the style linter", "why is CI failing on the docs check". Do not use when the project has no .vale.ini yet, or needs styles installed/configured — that's the vale-config skill. |
|
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 ls-configprints 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. - Before calling the
valebinary directly, check whether the target repo documents its own wrapper script for Vale (look in its README, CONTRIBUTING docs, pre-commit config, or ascripts/directory). Some projects wrapvaleto work around real bugs — e.g. a scope that silently stops matching multi-line YAML block-scalar frontmatter fields — and calling barevalein 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 callingvaledirectly; otherwise fall back to the default below.
Running vale
Default invocation (when the target repo has no documented Vale wrapper — see Gotchas):
vale <path-or-glob>
Key flags:
| Flag | Purpose |
|---|---|
--output=<style> |
Output format/template: CLI (default, human-readable), line (compact, one alert per line, good for grep/piping), JSON (for programmatic parsing), or a custom template. |
--minAlertLevel=<suggestion|warning|error> |
Overrides MinAlertLevel from .vale.ini for this run only, without editing config. |
--no-exit |
Forces exit code 0 regardless of findings. Use in CI stages that should surface lint output without hard-failing the build. |
--ignore-syntax |
Treats input as plain text, skipping format-aware parsing — use when a file's syntax-aware parser produces noisy or wrong results. |
vale sync downloads the packages/styles declared in .vale.ini — that's a one-time-per-change setup step (vale-config's territory), not part of a normal lint run. If a run behaves as though no styles are active, that's a sign vale sync hasn't been run yet, not a vale-run problem.
Prefer --output=JSON whenever the caller (a script, a CI step, another agent) needs to act on individual alerts rather than just get a pass/fail signal — CLI and line are for humans reading the terminal.
Fixing false positives
Scope the fix as narrowly as possible, in this order:
- One-off: inline-suppress the specific text run with the format's
vale off/vale onmarkup. - Recurring known-exception string, one rule: disable that specific rule for that specific match inline (e.g.
{/* vale Style.Redundancy["ACT test","OTHER"] = NO */}...= YES), rather than the whole rule. - Known project term failing spell check: add it to the style's
ignorelist, not an inline suppression.
Never disable a rule project-wide to fix one false positive — editing .vale.ini/BasedOnStyles is vale-config's job, and it silences the rule everywhere, not just the false-positive case.
If output looks wrong because Vale mis-parsed a file's format, rerun with --ignore-syntax before assuming the rule itself is broken.
For CI that fails solely because Vale returned non-zero on found alerts — not because the content is wrong for that pipeline stage — add --no-exit rather than disabling the rule.
If setting up Vale as a pre-commit hook or need the full inline-suppression/spelling-ignore syntax reference, read references/troubleshooting.md.