ktg-plugin-marketplace/CLAUDE.md
Kjell Tore Guttormsen e6b734c4fb docs(catalog): re-measure badge coverage at pinned refs (27 gated / 15 ungated across 12 plugins)
The 2026-08-02 reading (24 gated / 15 ungated across 7 of 11 plugins) predated
repo-standard entering the catalog and repo-mailbox badging its two remaining
axes. Re-measured 2026-08-04 at every pinned ref with the gate's own parsers:
42 catalog axis-claims, 27 badge-covered, 15 badge-less across 7 of 12 plugins,
source=ref for 12/12. The two readings reconcile exactly (24+3, 15-2+2).

Two premisses corrected while measuring:

- graceful-handoff has NOT lost its tests/hooks badges. Both badge-removing
  commits are unreleased (after v3.1.0), so at the pinned ref the catalog's
  "30 tests" is gated. Recorded at pickStatSource as the opposite failure
  direction to the llm-security case: reading the worktree misreports COVERAGE,
  not just values, and neither example alone would have caught it.

- the "251 selftest checks" correction is not settled: CLAUDE.md said 370,
  check-versions.mjs said 374, and repo-mailbox's own README at v0.19.0 implies
  390. Moot for the gate (badged and green at v0.20.2) and not re-measured, so
  the disagreement is flagged rather than laundered into one number.

Badge-less VALUES were not re-audited this session and do not need to be: only
two refs have moved since their audit, so all 15 stand measured at the ref they
are pinned to. Re-measurement is triggered by a ref moving, not by the calendar.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PtnSwCLpUR3Hk8SHkPoxX4
2026-08-04 21:43:52 +02:00

76 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ktg-plugin-marketplace (catalog)
Catalog repository for the ktg-plugin-marketplace. After the polyrepo migration this repo hosts only
the marketplace manifest and the catalog-level docs; every plugin and the shared design-system live in
their own Forgejo repositories under `https://git.fromaitochitta.com/open/`.
## What lives here
- `.claude-plugin/marketplace.json` — the marketplace manifest (plugin entries point at external repos)
- `README.md` — the landing/catalog page
- `CONVENTIONS.md` — marketplace-wide conventions inherited by every plugin repo
- `GOVERNANCE.md` — governance + fork-and-own model
- `.mailmap`, `.gitleaks.toml`, `.gitleaksignore` — shared git-hygiene baselines
## Catalog maintenance
- Marketplace conventions: see CONVENTIONS.md.
- Adding/updating a plugin entry: edit `.claude-plugin/marketplace.json` (external `source: "url"` with
a pinned `ref`) and re-state the plugin in README.md with its verified version.
- Plugin source, issues, and releases live in each plugin's own repository — not here.
- **Releasing a plugin (canonical path — `scripts/release-plugin.mjs`):** since the polyrepo split,
a release is a TWO-repo act — tag the plugin repo AND bump the catalog `ref`. Forgetting the second
step strands users on the old version (the exact drift this helper exists to prevent). Run
`node scripts/release-plugin.mjs <plugin> [--version X.Y.Z]` — dry-run by default; it REFUSES unless
`plugin.json` == README badge == the target version AND the `vX.Y.Z` tag exists, then prints the
planned bump. Apply with `--write [--commit] [--push]`; `--create-tag` mints+pushes a missing plugin
tag first. On `--write` it bumps the catalog `ref` AND the catalog README's per-plugin `` `vX.Y.Z` ``
label together (and `git add`s both on `--commit`). Because it only moves both to a verified, tagged,
consistent version, `check-versions.mjs` is green by construction. Never hand-edit a `ref` or a
README label for a release — use this. Pure planner + label reconciler covered by
`scripts/release-plugin.test.mjs`.
- **Version-consistency gate:** run `node scripts/check-versions.mjs` before committing any `ref`
change. For each plugin it checks (against the sibling repo) that the catalog `ref` resolves to a
real git tag (ERROR if dangling — breaks install), that `plugin.json` version == README
version-badge (ERROR), that the catalog README's per-plugin `` `vX.Y.Z` `` label == the catalog
`ref` (ERROR — the human-facing doc must not misstate the installed version), and that the catalog
`ref` matches `plugin.json` version (WARN — catalog lags or an unreleased bump). Exit 1 on any
ERROR; `--strict` also fails on WARN. Pure-function core covered by
`scripts/check-versions.test.mjs` (`node --test scripts/check-versions.test.mjs`).
- **Stat-badge mirroring (part of the same gate):** each plugin block in the catalog README ends in a
stat line (`7 agents · 16 scanners · 21 commands · 1398 tests · [Full documentation →]`). The gate
compares every number on that line against the plugin's own shields badge for the same axis, and
ERRORs when they disagree — the catalog must not overstate a plugin. **The rule is per-AXIS, not
per-plugin:** an axis the plugin does not badge is skipped silently, so there is no exception list
to maintain. **Re-measured 2026-08-04 at the pinned refs, all 12 plugins: 42 catalog axis-claims —
27 badge-covered · 15 badge-less across 7 of the 12 plugins** and therefore ungated. That supersedes
the 2026-08-02 reading (`24 · 15 across 7 of 11`); only two entries moved in between and both
reconcile exactly — repo-mailbox now badges the two axes it did not (`+2` gated, `-2` ungated) and
repo-standard entered the catalog (`+1` gated, `+2` ungated). The 15 ungated axes were hand-audited
at their pinned tags — 13 on 2026-08-02 (**14 of that pass's 15 were exact**; the defects were
repo-mailbox `6 CLI scripts` (true 8) / `251 selftest checks`, and voyage `500+ tests` against a
measured 832), and repo-standard's two on 2026-08-04. Since no ungated plugin's ref has moved
since its audit, every ungated value currently stands measured at the ref it is pinned to.
**⚠️ The `251 selftest checks` correction is itself unresolved and must not be cited as settled:**
three records disagree on the true value at v0.19.0 — this file said 370, `check-versions.mjs`
said 374, and repo-mailbox's own README at that tag implies 390 (`183 + 134 + 73`). It is moot for
the gate (repo-mailbox badges the axis now, 398 at v0.20.2, green) and was **not** re-measured
2026-08-04. It stands as the standing proof of the cost: an ungated number rots, and so does the
record of having fixed it.
`N+` in the catalog is read as a lower bound, not an equality, so `500+` was never gate-visible —
ungated axes rot in silence and need a re-run of this pass **whenever a ref moves**. **Never
hand-edit a stat line to silence the gate** — the plugin's badge is the source for every stat
number; fix the catalog to match it.
- **Counting rules for a badge-less axis (calibrated against the badged plugins, 2026-08-02).** When
the catalog must count an axis itself, count it the way the badges do, or the numbers stop being
comparable across plugin blocks: **hooks = hook COMMAND entries** in `hooks/hooks.json` (not
events, not matchers — the three diverge, and `commands` is what matched the badge on all 6 badged
plugins), and **tests = ` tests` from `node --test`**, not ` pass` (config-audit's badge 1398 is
its `tests` count; `pass` was 1375). Measure in an extraction of the tag
(`git archive <ref> | tar -x -C <tmp>`), never the sibling working tree.
- **The stat mirror reads the plugin README AT THE PINNED `ref`, never the sibling working tree.**
The catalog documents what *installs*, and that is the tag. A plugin that commits past its tag
without bumping its version — measured 2026-08-02 on both llm-security (scanners 23→22, tests
2013→2034) and config-audit (tests 1398→1441) — would otherwise make the gate demand that the
catalog restate unreleased numbers, which is exactly backwards. **When the gate flags a stat,
check `git show <ref>:README.md` in the plugin repo before believing the working tree.**