158 Commits

Author SHA1 Message Date
76e0df6f5b chore(plugins): patch-bump gitea for shipped content changes
gitea 1.3.2 -> 1.3.3. The round-1 Vale corpus fix (3324a73) changed
shipped skill content (gitea-issues, gitea-prs, gitea-releases SKILL.md)
without touching this plugin's manifests, so installed copies would keep
serving the old content from cache. Every other plugin whose content
changed in this PR got this bump (bin, kyberforge, lint, four times
total) — gitea was missed each time.

Marketplace entries carry no per-plugin version, so both marketplace.json
files are untouched, matching prior version-bump commits in this PR.

Refs: #85
2026-08-10 07:38:09 +00:00
680aa4f43c refactor(kyberforge): consolidate vale-wrap.sh's config parsing and subprocess spawns
Two efficiency findings from a code-review pass:
- The separated (--config X) and joined (--config=X) argument branches
  duplicated ~20 lines of absolutize-if-relative path logic. Extracted
  into abs_config_value(), used by both branches; the redundant
  --config=/* special case falls out since the helper already passes
  absolute paths through unchanged.
- The common single-file path spawned python3 twice per file (once for
  abspath resolution, once for flatten()). flatten() now optionally
  takes a tmpdir arg and does both in one process. The per-file loop
  under a directory argument is unchanged — that path wasn't flagged.

agent-audit's copy is canonical; skill-audit's copy was regenerated via
scripts/sync-vale-styles.sh, not hand-edited, to guarantee byte parity.
No hardening (bash 3.2 compat, surrogateescape, symlink guards) touched.
Verified: tests/test-vale-wrap.sh 39/39, check-vale-style-sync.sh clean,
full suite 12/12.
2026-08-09 20:14:23 +00:00
050aec4c80 docs(kyberforge): document Vale-wiring files in skill-audit/agent-audit READMEs
Both READMEs' file tables predate #85's Vale wiring and never picked
up scripts/vale-wrap.sh or the assets/vale/ style tree, so a reader
of either README had no way to find where the new Step 1 sub-check
actually lives. List the new files and note the Vale sub-check in
"What it does" for both skills.
2026-08-09 19:55:27 +00:00
0a41b2c7d3 fix(kyberforge): restore skill-audit's action-verb opening check
skill-audit's Description dimension implied Vale's DescriptionOpener
alert fully covers imperative-phrasing checks, but that rule only
matches the literal "This skill..." pattern. agent-audit kept its
equivalent manual "does the description open with a verb" fallback
bullet; skill-audit's got dropped when Vale wiring landed in #85,
leaving other non-imperative openers (gerunds, passive phrasing) to
sail through unflagged. Restore the parallel check.
2026-08-09 19:55:19 +00:00
997f0df23b chore(plugins): patch-bump kyberforge and lint for shipped changes
kyberforge 1.2.7 -> 1.2.8: both vale-wrap.sh copies, skill-audit's validate.sh
and its SKILL.md changed after the last bump. lint 1.1.4 -> 1.1.5: the Vale
research troubleshooting doc changed after its last bump.

Without the bump, installed copies keep serving the cached version. This is the
fourth time in this PR the bump was missed after shipped content changed —
check-manifests.sh validates parity between the two manifests but not that a
content change was accompanied by a bump, which is the gap that keeps letting
it through.

Refs: #85
2026-08-09 17:24:08 +00:00
302f6d0c19 fix(lint): tighten the SKILL.md word ceiling to 2770
MAX_WORDS=2900 was calibrated to the corpus median density and carried no
margin: at the densest observed 7.22 chars/word (~1.81 tokens/word) it permits
~5,240 tokens against the 5,000 it proxies for. 2770 holds the worst observed
density under the ceiling. The largest SKILL.md is 2,489 words, so the change
costs nothing today — 281 words of margin — and the header comment now argues
the new calibration rather than swapping the digits.

Both enforcement points move together, and a new test asserts they agree, since
a SKILL.md passing its own audit while the commit hook blocks it is the
disagreement this pair exists to prevent.

CONTEXT.md is deliberately left ungated: it is 2,816 words, and gating it would
block the build. Recorded here so the omission reads as a decision rather than
an oversight.

skill-audit's manual-fallback path listed only the line ceiling, so an agent
taking that path passed an oversized SKILL.md the hook then rejected. The word
ceiling is now named alongside it. agent-audit is deliberately unchanged: the
size hook scopes to SKILL.md only and agent-audit's validate.sh has no word
gate, so claiming it there would be false.

The Vale research doc still showed the MDX {/* vale off */} form under a
Markdown heading, contradicting CONTEXT.md and vale-run's troubleshooting
reference — that form suppresses nothing in plain .md. Fixed in both places it
appeared.

tests/run-tests.sh used mapfile (bash 4.0+) with unguarded array expansion,
though AGENTS.md tells contributors to run it and macOS ships bash 3.2. It now
collects via a while-read loop over process substitution and guards every
expansion. The newline-delimited find|sort pipeline is kept rather than -print0
with sort -z, whose BSD portability is the weaker link, and which matches
mapfile -t's previous behaviour exactly.

Refs: #85
ADR: 0013
2026-08-09 17:23:51 +00:00
ad1e5aaa9b fix(kyberforge): carry apostrophes verbatim through a |- literal block
The flattener's last-resort branch rewrote ASCII ' to U+2019, justified as the
one combination no YAML scalar can carry verbatim. That claim was false: a |-
literal block with a single indented content line carries ', ", \ and ": "
verbatim and keeps text.frontmatter.description matching — as the wrapper's own
docstring already said of literal blocks. The rewrite fired on 12 of 54
in-scope files, silently disabling every rule whose token contains an
apostrophe. Case 20 pinned only that the scope stayed alive, so it passed
either way.

The emission site now splits the emitted scalar on its first newline so a
carried-over trailing comment stays on the "description: |-" header line rather
than becoming part of the value, and pads by span_lines - 1 - newlines. The pad
stays non-negative because the branch is only reachable when the original span
is at least two lines. Verified across all 73 in-scope files: no line-count
changes, and exactly the 12 expected files take the new branch.

One reported position moves: an alert on a description that is itself flagged
shifts from the key line to the block's content line, both inside the original
span. YAML cannot put a literal block's content on the key's own line, so this
is unavoidable; no line at or after the end of any description span moves.

Also: --output no longer absolutises the built-in style names line, JSON and
CLI, which a same-named file or directory in cwd turned into a template path
(exit 2, E100 Runtime error). And case 19's empty-baseline guard no longer
lets five dependent comparisons print vacuous passes — while fixing it the
guard turned out to be unreachable, since under pipefail an alert-free report
aborted the script at the assignment.

Refs: #85
ADR: 0014
2026-08-09 17:23:24 +00:00
57654c4b02 docs(lint): correct the Vale scalar, size-ceiling and release-gate claims
Four claims in shipped agent-facing docs did not match verified behaviour.
These are read as ground truth by agents in other repos, so each was
reproduced against vale 3.15.2 before rewriting:

- CONTEXT.md and `vale-config/SKILL.md` said both `>` and `|` block scalars
  break the description scope. `|` does not — it lints normally and fires every
  alert, while `>` yields zero. An agent following the old text would rewrite a
  working `|` description into a plain multi-line scalar, which genuinely does
  break, inverting the intended remediation. Both now name the forms that do
  break and state that `|` does not.
- CONTEXT.md and ADR-0013 described the size hook as failing only above 500
  lines, omitting the 2900-word gate it also enforces. Both now describe the
  pair and state that `validate.sh` checks the same two.
- ADR-0014 recorded an accepted residual — a wholesale `assets/` deletion going
  unflagged — that commit 14c2c91 closed. Left as the point-in-time record and
  amended with an update describing the union-with-tag-manifest mechanism,
  following the amendment precedent in ADR-0005.
- `vale-config/SKILL.md` asserted a fresh `.vale.ini` fails until `vale sync`
  runs, contradicting its own note that built-in styles need no download. The
  claim is now scoped to package styles; this repo's two configs declare no
  packages and lint clean with zero syncs.

Also repoints AGENTS.md at the seven `gitea:*` skills — the `bin:gitea` route
it named no longer exists.

Refs: #85
2026-08-09 15:44:28 +00:00
4ae2429840 fix(kyberforge): align the audit word ceiling and drop the fragile --config
Three divergences between what the audit skills claim and what the hooks
enforce, each of which fails silently rather than loudly:

- `skill-size-check.sh` blocked at 2900 words while `validate.sh` checked only
  the 500-line ceiling, so `/skill-audit` could report a skill ready to ship
  that the commit hook then rejected. `validate.sh` now checks the same pair on
  the same inclusive terms; the constants are duplicated with a comment naming
  the other file, because a plugin skill's scripts cannot read outside the
  plugin directory once installed to the cache.
- Both audit skills' Step 1 passed `--config assets/vale/.vale.ini`, which is
  redundant (the wrapper self-locates its sibling config) and fragile: an agent
  that resolves the script path against the skill directory but not the config
  path gets E100, exit 2, which the surrounding fallback clause misreads as
  "vale unavailable" and downgrades to full LLM judgment with no signal.
- The external-consumer test registered only the two Vale hooks, never the
  third shipped hook, so a lost executable bit would have broken every consumer
  while the local suite stayed green. Verified by mutation: `chmod 644` on the
  copied script now turns three passes into two failures.

Also corrects the size hook's calibration comment, which claimed ~5.7-6.5
characters per word against a corpus whose measured median is 6.79 — the stated
upper bound sat below the median, so the "calibrated with margin" claim was
inverted for prose-dense files. MAX_WORDS is unchanged pending a decision; the
comment is now explicit that the gate holds under 5,000 tokens for typical
prose density, not for any file.

Refs: #85
2026-08-09 15:44:16 +00:00
aa8cc22695 fix(lint): flatten every multi-line description form in vale-wrap.sh
Vale locates a frontmatter description by matching the parsed YAML value back
against the source text, so any scalar whose value is not spelled out verbatim
loses the `text.frontmatter.description` scope entirely. The wrapper only
flattened `>` folded scalars, so plain, double-quoted and single-quoted
multi-line descriptions silently reported zero alerts and exit 0 — a clean pass
indistinguishable from a real one, in a prefilter whose callers are instructed
not to re-derive its verdict by judgment.

Implementation notes:

- Classify the scalar kind after `^description:[ \t]*` and reuse one shared
  continuation-line generator for every form; `|` literal blocks keep their
  line breaks, stay verbatim-matchable, and are still left untouched.
- Emit the flattened value in whichever scalar form needs no escape at all
  (plain, then single-quoted, then double-quoted), because any escape breaks
  the verbatim match. The old blanket `'` -> U+2019 substitution silently made
  apostrophe-bearing rule tokens unmatchable across 63% of the corpus; it now
  survives only for the one combination no YAML scalar can carry verbatim.
- Terminate continuations at a line flush with the key, not only on a shallower
  indent — a `description:` followed by a flush-left line previously swallowed
  the rest of the frontmatter.
- Route vale's value-taking flags explicitly instead of inferring targets by
  file existence, and absolutize relative `--output`/`--path` values the way
  `--config` already was, since the run `cd`s into the scratch mirror.
- Fail loudly on a nonexistent path instead of inheriting bare vale's fallback
  to stdin, which rendered a typo'd path as `0 errors ... in stdin`, exit 0 —
  a form the callers' `0 files` NOT-RUN guard cannot match.
- Follow symlinks when walking a directory argument, matching bare vale.

Refs: #85
2026-08-09 15:44:04 +00:00
16c038b178 fix(lint): guard empty array expansions in vale-wrap.sh for bash 3.2
Under set -u, "${arr[@]}" on an empty array aborts on bash before 4.4,
which is what macOS ships as /bin/bash. Three expansion sites now use
${arr[@]+"${arr[@]}"} consistently.

The hazard is not currently reachable: verified on a bash 3.2.57 built
from source that all seven invocation shapes succeed against the
previous code, including zero args, flags-only and an empty directory.
vale_args is provably non-empty at every site because the default
--config branch always appends first. The guard is kept because that
invariant is non-local and untested, so an edit to the default-config
branch would reintroduce a macOS-only crash silently.

Test fidelity is deliberately mixed. Case 16 is static and is the only
one that fails against the previous code, since no bash 5 host can
reproduce the abort at runtime. Case 17 runs the emptiest invocations
under the oldest bash it can find and names that shell in its output
so it cannot overclaim. Case 18 guards against the tempting wrong fix
of dropping the quotes, which also silences the abort but word-splits
a path containing a space.

No other bash 4.x construct is present; swept for mapfile, declare -A,
case modification, negative indices, globstar, wait -n and namerefs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MCQ648fLSFXPHGZdQ8gn58
2026-08-09 13:32:30 +00:00
cc5f366450 chore(plugins): patch-bump kyberforge and lint for shipped changes
kyberforge 1.2.5 -> 1.2.6 for the self-locating vale-wrap.sh.
lint 1.1.3 -> 1.1.4 for the corrected Vale exit-code semantics: a
consumer cached at 1.1.3 holds docs that lead to building a gate which
passes everything.

Both provider manifests bumped in parity per ADR-0006. Marketplace
entries carry no per-plugin version, so neither file changes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MCQ648fLSFXPHGZdQ8gn58
2026-08-09 13:06:53 +00:00
e9234f6d8a docs(lint): correct the Vale exit-code and glob-scoping claims
cli-reference.md said vale exits non-zero for any alert at or above
MinAlertLevel. The exit code keys on error-level alerts alone;
MinAlertLevel filters display only. LESSONS.md records this exact
misconception as costing two review rounds, and this research doc is
the cited provenance source for the skills that state it correctly.

CONTEXT.md claimed a SKILL.md outside plugins/ matches no glob section.
[**/SKILL.md] matches any path ending in SKILL.md — the sentence is a
stale leftover from the path-scoped globs at cbc33d9, and contradicted
its own paragraph two sentences earlier. The NOT-RUN 0-files guard it
justifies is correct and is unchanged; only the rationale was wrong.
CONTEXT.md also cited the local files: regex as the scoping mechanism,
where the shipped manifest deliberately stays layout-agnostic.

ADR-0014 records the entry[0]-only prefixing constraint as the reason
the self-locating design is required, and that no entry may grow a
repo-internal path argument.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MCQ648fLSFXPHGZdQ8gn58
2026-08-09 13:06:52 +00:00
8c570e9659 fix(lint): make the Vale prefilter work for external consumers
pre-commit prefixes only entry[0] with the hook-repo clone path
(cmd = (prefix.path(cmd[0]), *cmd[1:])), so the --config argument in
.pre-commit-hooks.yaml resolved against the *consuming* repo's root
and hard-failed every external run with E100. Two of the three hooks
ADR-0014 promises were unusable.

vale-wrap.sh now self-locates its config from BASH_SOURCE when no
--config is supplied; an explicit --config still wins in all three
argv forms and stays cwd-relative. Both manifests drop the argument
and are kept byte-identical: the local repo: local config resolved
--config correctly only because the consuming repo *was* this repo,
and that divergence is why three review rounds missed the defect.

Also in the wrapper:
- replace GNU-only `realpath -m` with a portable abspath helper; -m is
  load-bearing (dest does not exist yet), so BSD realpath aborted the
  script under set -e on macOS
- walk directory arguments instead of passing them through unflattened,
  which reported a clean 0-error run for files that fail when named
  explicitly
- read/write with errors='surrogateescape' so one non-UTF-8 .md under a
  directory argument cannot abort the hook

New test-vale-hooks-consumer.sh builds the hook repo from the working
tree and points a file:// consumer at it, covering the manifest as a
hook repo for the first time.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MCQ648fLSFXPHGZdQ8gn58
2026-08-09 13:06:23 +00:00
1164f3abad fix(lint): make Vale prefilter portable via the plugin
skill-audit/agent-audit's Step 1 resolved vale-wrap.sh/.vale.ini via
`git rev-parse --show-toplevel`, which returns whichever repo the skill
happens to run in. Inside ai-development that works; in any external repo
that installs kyberforge@holocron as a plugin, it resolves to that repo's
own root, which has no .vale.ini — the prefilter silently fell back to
full LLM judgment. ADR-0013 named this as a deliberately deferred gap.

Vale's config/styles/wrapper now ship inside the plugin itself: a
canonical copy in agent-audit/assets/vale/ (Kyberforge + KyberforgeCopilot,
the superset agent-audit needs) and a smaller duplicate in
skill-audit/assets/vale/ (Kyberforge only) — per the no-cross-skill-path
rule already established for plugin cache-installs. Both skills resolve
these relative to their own directory, same as scripts/validate.sh
already does.

A new root .pre-commit-hooks.yaml exposes both copies plus
skill-size-check so any external repo can enforce the same rules via
`repo: <this-repo-url>, rev: <tag>` in its own pre-commit config,
independent of Claude Code entirely — the same mechanism covers CI. This
repo's own pre-commit hook now consumes the identical plugin-bundled
copies via repo: local (not a third root copy, and not a pinned
self-reference, which would lint working-tree edits against the last
tagged release instead of the change being made). Split into
vale-audit-prefilter-skill/-agent hooks after confirming, by diffing the
full corpus against both old and new config before deleting the old
files, that one combined hook pointed at only one copy silently 0-file-
skips the other file type.

scripts/check-vale-style-sync.sh guards the two copies against drift,
wired at pre-push alongside check-manifests.

ADR: 0014
2026-08-09 10:04:19 +00:00
aff5b6c4c8 chore(plugins): patch-bump bin, kyberforge and lint for shipped content changes
The round-3 fixes changed shipped skill content in three plugins without
touching their manifests, so installed copies would keep serving the old
content from cache. plugin-author requires a patch bump for exactly this
reason: consumers use the version to detect changes.

It matters most for lint — anyone installed at 1.1.2 has a cached
vale-run/SKILL.md stating that Vale exits non-zero on warnings, which is
backwards and would lead them to build a gate that passes everything.

- bin        1.1.0 -> 1.1.1  (caveman: suppression comments removed)
- kyberforge 1.2.3 -> 1.2.4  (skill-audit/agent-audit: Vale step reworked)
- lint       1.1.2 -> 1.1.3  (vale-run: exit-code and suppression-syntax fixes)

Marketplace entries carry no per-plugin version, so both marketplace.json
files are unchanged.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MCQ648fLSFXPHGZdQ8gn58
2026-08-08 20:45:13 +00:00
149d564f6a fix(lint): make the Vale gate actually gate, drop VagueQualifier
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 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MCQ648fLSFXPHGZdQ8gn58
2026-08-08 20:42:15 +00:00
210b192613 docs(lint): add docs index for Vale research docs
plugins/lint/docs/research/docs/vale/ had no top-level index pointing
into it, unlike plugins/kyberforge/docs/README.md which indexes its
own research directories. Add plugins/lint/docs/README.md mirroring
that convention: one line per file describing what it covers, plus a
provenance note tying the directory back to plugins/lint/sources.md
and the vale-config/vale-run skills that consume it.

Closes out a follow-up item from PR #85's review.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MCQ648fLSFXPHGZdQ8gn58
2026-08-08 20:21:21 +00:00
792d3e1852 fix(lint): resolve round-1 and round-2 review findings on the Vale prefilter
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
2026-08-08 20:21:21 +00:00
3324a73225 feat(lint): expand Vale audit prefilter into a broader plugin-content harness
Deferred item from PR #85 review. Per ADR-0013: cherry-picks two low-noise
rules from trialing write-good/alex against the real corpus (VagueQualifier,
SentenceOpenerThereIs) into styles/Kyberforge rather than adopting either
package wholesale (both are tuned for blog prose and were noisy on this
repo's terse, imperative instruction files - see the ADR's rejected-rule
list). Adds a new skill-size-check pre-commit hook enforcing agentskills.io's
500-line/5,000-token SKILL.md ceiling, currently unenforced. Fixes the 28
resulting violations across 20 existing SKILL.md/agent files so the
enforcing pre-commit hook lands clean.

governance.md/CONTROLS.md were evaluated and excluded as rule sources -
they're org/CI-infrastructure controls, not prose patterns Vale can express.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QUDczvw1H3eEeMD29Q9Lbi
2026-08-08 20:20:58 +00:00
544392be98 refactor(lint): genericize lint-runner dispatch and manifest wording
lint-runner's description already promised other linters could be added
without changing its own contract, but Process hardcoded vale-config/
vale-run and .vale.ini by name. Switch to <linter>-config/<linter>-run
naming-convention dispatch so the promise holds. Drop the explicit
Vale callout from the plugin manifests' description/keywords to match.

Addresses a deferred item from PR #85 review.
2026-08-08 20:20:58 +00:00
bbb0dcd21a fix(lint): flatten multi-line frontmatter descriptions before Vale runs
Vale's text.frontmatter.description scope silently stops matching once
the description is a YAML block scalar spanning 2+ physical lines —
the style used by most skills/agents in this repo. scripts/vale-wrap.sh
flattens the description to one line in a scratch copy (preserving the
repo-relative path and total line count) before invoking real vale, and
both audit skills plus the pre-commit hook now call it instead of vale
directly. Also tightens the pre-commit hook's file glob to single path
segments so it can't cross into docs/research examples or asset
templates the way the audit skills' scoped invocations already avoid.

Addresses PR #85 review feedback.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FxG5T8EJDgkABXxuneuFfn
2026-08-08 20:20:58 +00:00
cbc33d952e feat(kyberforge): wire Vale as deterministic prefilter for skill-audit/agent-audit
Adds repo-root .vale.ini plus a custom Kyberforge style (description-opener,
vague-wording, and generic reference-pointer padding rules) and a
KyberforgeCopilot style scoped to .agent.md files (Use proactively check).
skill-audit and agent-audit Step 1 now run vale against the specific file(s)
being audited and defer the corresponding Description/Patterns/Body checks
to its output instead of re-deriving them by LLM judgment, per the split
proposed in issue #84.

Closes #84

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FxG5T8EJDgkABXxuneuFfn
2026-08-08 20:20:58 +00:00
f326df4861 chore(lint): register lint plugin in marketplace and document scope
Adds the lint plugin entry to both marketplace manifests and records
the resolved scope/structure decisions from grilling in CONTEXT.md:
standalone repo-agnostic plugin, split vale-config/vale-run skills,
report-only lint-runner agent, audit-pipeline wiring deferred.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FxG5T8EJDgkABXxuneuFfn
2026-08-08 20:20:58 +00:00
57bdfa92e8 fix(lint): resolve audit findings on vale skills
Merge duplicate gotcha in vale-config (Packages vs BasedOnStyles was
stated twice) and align vale-run's category field with vale-config's
(lint, not linting) so sibling skills in the plugin agree.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FxG5T8EJDgkABXxuneuFfn
2026-08-08 20:20:58 +00:00
59ad2a3cbd feat(lint): add lint-runner agent
Report-only agent that composes vale-config/vale-run to run a lint
sweep over a scope and return normalized findings — no Edit tool, it
flags issues rather than fixing them. Also lands the plugin manifest
scaffold (plugin.json, .claude-plugin/plugin.json) that the earlier
vale-config/vale-run skill commits assumed but didn't carry, bumped
to 1.1.0 for the new agent.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FxG5T8EJDgkABXxuneuFfn
2026-08-08 20:20:58 +00:00
8b00728374 feat(lint): add vale-run skill
Covers invoking the vale CLI and interpreting its output — output
formats, severity filtering, exit-code handling, and false-positive
triage — for an already-configured project.
2026-08-08 20:20:58 +00:00
d1afdbeff7 feat(lint): add vale-config skill
Covers Vale install and .vale.ini setup — StylesPath, built-in/
third-party/custom styles, BasedOnStyles activation. Setup half of
Vale support; vale-run (running/interpreting) is a separate skill.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FxG5T8EJDgkABXxuneuFfn
2026-08-08 20:20:58 +00:00
5e22672189 docs(kyberforge): add vale.sh research docs
Prep work for issue #84 - gathers Vale (vale.sh) config, styles/rules,
CLI, installation, and troubleshooting reference material into
plugins/kyberforge/docs/research/docs/vale/ alongside the existing
research topics.

Refs #84
2026-08-08 20:20:58 +00:00
1764781d10 chore(plugins): bump bin and gitea versions for skill relocation
plugins/bin loses a whole skill (gitea removed) — minor bump (1.0.5 ->
1.1.0) to reflect the capability-surface change. plugins/gitea gains a
reference file and a README fix, no new capability — patch bump
(1.3.1 -> 1.3.2).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 18:08:46 +00:00
3a1305c438 chore(gitea): remove old flat gitea skill, superseded by plugins/gitea
The deep-module split in plugins/gitea/ (ADR 0011) already covers every
domain the old plugins/bin/skills/gitea/ flat skill handled. Move its
token-access.md into plugins/gitea/references/ first, since it held
empirical scope-test results (Actions/CI, Wiki, Notifications, Packages,
User/Org) not reproduced anywhere in the new plugin, then drop the old
skill and fix a stale cross-reference pointing at it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 18:04:37 +00:00
bb34aa0eb5 feat(core): add content-guide.md to agentsmd-author
PR review feedback: Step 3 gave no concrete guidance on what good
AGENTS.md content looks like, and the skill had no substantive
references file (only provenance bookkeeping in sources.md), unlike
sibling kyberforge skills. Adds section-by-section content guidance,
the worked example, and monorepo precedence rules synthesized from
the agentsmd research corpus.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 17:40:27 +00:00
250c486ce1 docs(core): add plugin README 2026-07-23 17:31:14 +00:00
d6b0292da7 chore(core): bump version to 1.1.0 for new skill content
core gained three skills for the first time (agentsmd-author,
agentsmd-audit, provider-adapter-author). Minor bump reflects new
capability rather than a fix. Also declares the missing `skills`
path in the Copilot manifest so Copilot CLI discovers them
(CC auto-discovers from the plugin root; Copilot requires explicit
declaration per ADR-0016 convention).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 17:29:02 +00:00
956ff7a54a feat(core): add agentsmd-author skill
Creates/updates a target repo's AGENTS.md by exploring real repo
conventions, supports nested monorepo placement, closes out via
agentsmd-audit, and composes into provider-adapter-author for
provider-file reconciliation. Completes the three-skill trio from
ADR-0012.
2026-07-23 17:25:43 +00:00
6fd6876264 feat(core): add provider-adapter-author skill
Converts a target repo's provider-specific instruction file (CLAUDE.md,
.cursor/rules, copilot-instructions.md, etc.) into a thin adapter over
AGENTS.md, mirroring this repo's own two-tier CLAUDE.md pattern
(ADR-0002/0003). Self-validates via a bundled deterministic script
(scripts/validate-adapter.sh) rather than a separate paired audit skill.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 17:19:17 +00:00
04e7006f76 fix(core): list scripts/ and tests/ READMEs in agentsmd-audit file table
Independent clean-context audit recheck flagged that README.md's file
table omitted scripts/README.md and tests/README.md despite both
existing on disk, inconsistent with sibling kyberforge skills.
2026-07-23 17:12:17 +00:00
6c8ea8e8f0 feat(core): add agentsmd-audit skill files
The previous commit only landed the research-folder rename — a multi-path
git add silently failed and left CONTEXT.md, ADR-0012, and the actual skill
files unstaged. This lands them: the agentsmd-audit skill itself (three
deterministic validators for secrets, structure, and drift against a target
repo's AGENTS.md), its bats test suite, provenance record, and the
CONTEXT.md/ADR entries documenting why this lives in core rather than
kyberforge.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 17:08:19 +00:00
40a045958f feat(core): add agentsmd-audit skill
Audits a target repo's AGENTS.md file(s) for embedded secrets, structural
completeness against the agents.md common-sections checklist, and drift
(referenced commands/paths that no longer resolve). First active skill in
the core plugin — kyberforge is scoped to marketplace-factory meta-tooling,
not generic target-repo documentation (see ADR-0012). Moves the agentsmd
research corpus from plugins/kyberforge to plugins/core to match.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 17:06:48 +00:00
Claude Code AI - Gitea MCP
bc7b3ecdbf refactor(gitea): deep modules — split flat dispatch skill into 6 domain skills + orchestrator + agent (#67) 2026-07-05 19:53:26 +00:00
c60ec5f2f7 chore(kyberforge): bump plugin version to 1.2.3
skill-author and agent-author SKILL.md files received bug fixes (git-log
commit-hash verification before reporting completion, skill-author now
forbids self-spawning audit/recheck subagents during its authoring pass,
and agent-author closed checklist/coverage gaps). Patch bump to reflect
fixed behavior, not new capability.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FNJWdVvdgvZCHi1hZGqgVQ
2026-07-05 13:20:07 +00:00
f657123931 fix(kyberforge): fix checklist/action mixing and improve-flow source_keys gap in agent-author
The Prerequisites checklist mixed items to confirm (preconditions) with an
action to perform (capturing git log), so the following "stop and ask if
missing" gate didn't logically apply to the git-log step. The improve flow
also had no reminder to update source_keys/sources.md when an edit touches
research-sourced content, unlike the create flow's explicit step for it.

Refs #69
2026-07-05 13:20:07 +00:00
fe24f7d900 fix(kyberforge): close agent-author frontmatter-comment and audit-availability gaps
Independent skill-audit found that agent-author's closing checklists never
verified template <!-- --> comments were stripped from frontmatter (produces
invalid YAML if left in), the Copilot field-exclusion checklist omitted two
fields present in the authoritative list, and the improve flow had no
agent-audit availability check unlike the create flow.
2026-07-05 13:20:07 +00:00
b0903f190a fix(kyberforge): require commit-hash verification in agent-author
Prior sessions had authoring subagents report completion after only
staging changes (git diff --stat showing output, but no git commit).
agent-author's create and improve flows now require capturing
git log --oneline -1 before and after the authoring pass and asserting
the hash actually changed via a real commit, matching the fix already
applied to skill-author.

Refs #69
2026-07-05 13:20:07 +00:00
3eb216afa6 fix(kyberforge): use consistent slash-command form for forge reference
Refs #69, #71
2026-07-05 13:20:07 +00:00
fc79acfa05 fix(kyberforge): tighten skill-author checklist/phrasing/reference style
Address round-2 independent-audit suggestions: single-item checklist
misuse in the improve flow, inaccurate "before Step 1" phrasing, and an
unbackticked cross-skill reference to kyberforge:forge.

Refs #69, #71
2026-07-05 13:20:07 +00:00
8b92590dc9 fix(kyberforge): surface commit-hash checklist earlier, drop redundant scripts line in skill-author
Independent /skill-audit recheck flagged the git-log-capture instructions
as discoverable only at close-out (Step 6/Step 5), long after the step
where the hash should actually be snapshotted. Adds the capture checklist
item to Prerequisites (create flow) and Step 1 (improve flow) instead of
leaving it as a retrospective-only note. Also drops a sentence in the
improve flow's Step 4 that duplicated the preceding one on editing
scripts/reference files directly.

Refs #69
2026-07-05 13:20:07 +00:00
caebc42bad fix(kyberforge): require commit-hash verification and forbid self-spawned rechecks in skill-author
Prior sessions had authoring subagents report completion after only
staging changes (git diff --stat showing output, but no git commit),
and one run self-spawned its own audit/recheck subagent instead of
leaving that to forge's outer loop, losing an uncommitted draft when
the stray subagent's worktree was torn down.

Refs #69, #71
2026-07-05 13:20:07 +00:00
a43820725f fix(install): resolve git hooks dir via git plumbing, drop stale manifest fields
scripts/install.sh hardcoded $REPO_ROOT/.git/hooks, which breaks under any
git worktree checkout (.git is a file there, not a directory) — this is
what blocks every worktree-based agent from pushing cleanly. Resolve the
hooks directory via `git rev-parse --git-path hooks` instead, normalizing
to an absolute path since git returns it relative to the queried repo root
for plain checkouts but absolute for worktrees.

Also drops `agents`/`skills` fields from plugins/bin, plugins/core, and
plugins/gitea plugin.json where the referenced directories don't exist on
main yet (bin never had an agents/ dir; core and gitea's real skill/agent
content is still pending merge from an in-flight branch) — these were
failing scripts/check-manifests.sh and blocking pushes for unrelated work.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FNJWdVvdgvZCHi1hZGqgVQ
2026-07-05 12:44:26 +00:00
642e4fd142 fix(kyberforge): broaden audit self-triggers, plug factory gaps
skill-audit/agent-audit now proactively trigger after a skill/agent
file is hand-edited outside skill-author/agent-author, not just on
explicit request — closing a gap from this session where a fork's
direct edits to agent-author/agent-audit shipped without their own
inline audit until forge was invoked to check afterward.

Also: plugin-author gains a gotcha on claude plugin validate --strict
auto-discovering every .md under agents/ regardless of manifest
declarations (ADR-0010); agent-audit's dimension count and
validate-provenance.sh's --help now match actual behavior.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-05 09:34:59 +00:00