Per-repo gate for the open/ presentation standard: README first screen, install block, files required by the repo's class, and dead repo references.
  • JavaScript 100%
Find a file
Kjell Tore Guttormsen 816ba97c63 feat(repo-standard): v0.1.0 - per-repo gate for the open/ standard
Five checks a single repository can answer on its own: README first
screen, install block, files required by its class, open/<name>
references, description length. Pure classifiers with I/O resolved into
their input, mirroring check-versions.mjs; ERROR/WARN/SKIP/OK, exit 1
on ERROR. 32 tests.

The reference check has THREE outcomes: "matches no repo" (ERROR) is
separate from "matches a known non-repo" (WARN). Sharing an outcome
would let real dead links hide inside correct text. Only names in URL
position count, and .git is normalised first - without that a raw scan
turns 3 dead names into ~20.

enabledPlugins is treated as a legitimate second install form; what the
gate requires in addition is a CLI command. The JSON form is never
reported as the defect.

STATE.md is gitignored from this first commit - public remote.
No hook yet: a blocking gate must first be precise enough not to fail a
correct repository.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WYJ3FHLtVgzFXMZ6UF598h
2026-07-27 09:10:46 +02:00
.claude-plugin feat(repo-standard): v0.1.0 - per-repo gate for the open/ standard 2026-07-27 09:10:46 +02:00
register feat(repo-standard): v0.1.0 - per-repo gate for the open/ standard 2026-07-27 09:10:46 +02:00
scripts feat(repo-standard): v0.1.0 - per-repo gate for the open/ standard 2026-07-27 09:10:46 +02:00
skills/repo-standard feat(repo-standard): v0.1.0 - per-repo gate for the open/ standard 2026-07-27 09:10:46 +02:00
.gitignore feat(repo-standard): v0.1.0 - per-repo gate for the open/ standard 2026-07-27 09:10:46 +02:00
CHANGELOG.md feat(repo-standard): v0.1.0 - per-repo gate for the open/ standard 2026-07-27 09:10:46 +02:00
CLAUDE.md feat(repo-standard): v0.1.0 - per-repo gate for the open/ standard 2026-07-27 09:10:46 +02:00
LICENSE feat(repo-standard): v0.1.0 - per-repo gate for the open/ standard 2026-07-27 09:10:46 +02:00
package.json feat(repo-standard): v0.1.0 - per-repo gate for the open/ standard 2026-07-27 09:10:46 +02:00
README.md feat(repo-standard): v0.1.0 - per-repo gate for the open/ standard 2026-07-27 09:10:46 +02:00

repo-standard

Per-repo gate for the open/ presentation standard: README first screen, install block, files required by the repo's class, and dead repo references.

A repository can be substantially good and still read as abandoned. The gap is almost never the code — it is the first screen, an install path that stops halfway, and references to a name that was retired two renames ago. This plugin checks that surface in one repository and reports what it finds.

Solo-maintained, fork-and-own. This plugin is a starting point, not a vendor product. Issues are welcome as signals; pull requests are not accepted. See the marketplace governance for the full model.

AI-generated: all code produced by Claude Code through dialog-driven development.

Version Platform Skills Tests License

Install

Use the https:// form. The forge UI's clone button hands out an ssh:// URL, and marketplace add answers it with Invalid git URL — a message that never mentions the protocol.

claude plugin marketplace add https://git.fromaitochitta.com/open/ktg-plugin-marketplace.git
claude plugin install repo-standard@ktg-plugin-marketplace

Or enable it directly in ~/.claude/settings.json — a working second path, not a replacement for the two commands above:

{ "enabledPlugins": { "repo-standard@ktg-plugin-marketplace": true } }

Requirements

Node 18 or newer. No dependencies. The one network call — the org listing, used to read a repo's published description — reads anonymously, so it needs no token; --offline skips it.

What it does

Run it inside a repository:

node scripts/repo-standard-check.mjs --dir "$PWD"

It checks five things, and the repository's class decides what each one means:

Check What fails it
First screen # <name> is not line 1, or the line under it is not the published description
Install block the form for this class is missing, incomplete, or shown over ssh://
Required files a file this class needs is absent
References an open/<name> in URL position resolves to nothing
Description empty, or past the length bound

Findings are ERROR, WARN, SKIP or OK; the process exits 1 on any ERROR. A SKIP means the check could not run — an unreachable forge, a repo that is not in the register. It is not a pass, and the output says which.

The class decides what is required

The class is read off the catalog and the remotes; it is structural, not a judgement. It lives in register/repos.json.

Class Install form Requires
plugin marketplace add and a CLI install command README, LICENSE, CHANGELOG, plugin manifest
catalog marketplace add only — it is the marketplace + GOVERNANCE, CONVENTIONS
shared-asset how to vendor it; never a plugin install line README, LICENSE
standalone pip/uv README, LICENSE
org-profile none README

A flat standard across every class would demand a CONTRIBUTING from a CSS library that accepts no contributions, and a roadmap from a five-line profile. That is how a gate teaches people to switch it off.

Three outcomes on references, not two

"Matches no repository" and "matches something that is deliberately not a repository" are different findings. The second class is real and it is common: a retired name kept alive on purpose in prose, a reserved namespace occupying a repo-shaped path, a published package name that was never a repo. If those share an outcome with genuine dead links, the genuine ones hide inside a pile of correct text.

Only names in URL position are treated as references, which excludes prose, paths and directory names in one move. The .git suffix is normalised first — without that, a raw scan turns three dead names into about twenty.

Non-goals

  • Anything requiring a view across every repository at once. This gate sees one repo. A README can look correct from the inside and only turn out wrong when a dozen are compared. Org-wide divergence is measured where the org is enumerated, not here.
  • Fixing while measuring. It records findings; you fix them afterwards. Patching under measurement is how inconsistency accumulates unnoticed.
  • Deciding whether to rename a repo, or whether a roadmap is real. Those are operator calls. The gate brings evidence to them.
  • Blocking commits. There is no hook. A gate that fails a correct repository is the mechanism that gets gates switched off, so this one earns that role before it takes it.

Tests

npm test

32 tests over the pure classifiers. The reference fixtures are the measured false positives that produced the three-outcome rule, each with its expected verdict.

Changelog

See CHANGELOG.md.