repo-standard/register/repos.json
Kjell Tore Guttormsen 720850a9ad feat(gate): buckets, traits, and the checks the brief calls load-bearing
Measured this build against a documentation brief for public repos. The
five original checks covered roughly one of its ten sections, so this
adds what a single repo can answer on its own.

New: required README headings per class (Non-goals is the cheapest
trust-builder there is), in-repo version consistency across manifest /
badge / CHANGELOG / tag, badge honesty, boilerplate, licence-claim,
and relative links. Findings now carry a BUCKET beside the level -
broken / missing / weakening - and output is grouped by it, because
that is the order the work gets done in.

Traits are a second axis beside class: class is structural and readable
off the catalog, a trait says what the code does. `security` attaches
SECURITY.md and a Known limitations section. The two names carrying it
are proposed, not measured - that list is the operator's.

Solo-maintained settles a category: CONTRIBUTING, CODE_OF_CONDUCT and
MAINTAINERS are required by no class. Consumer-facing documents are
untouched by that; SECURITY.md exists for the stranger who finds a hole.

Three bugs found by running against llm-security, not by reading:
- ~30 link findings, all noise. Regexes inside code spans are
  `[...](...)` to a naive scanner. Strip code first.
- `file:` and other schemes were treated as repo-relative paths.
- Relative links were resolved against the repo root instead of the
  file they sit in, calling two files missing that sat next to the
  README linking them.
Same fix applied to the boilerplate check: a document ABOUT placeholder
detection was tripping the placeholder detector.

Also removed this repo's own static tests badge. There is no CI - the
forge has zero Actions runners registered - so it could never become
real, and it is the exact anti-pattern the gate now flags.

67 tests. Against llm-security every remaining finding is real and
matches the census's independent hand-measurement.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WYJ3FHLtVgzFXMZ6UF598h
2026-07-27 16:06:33 +02:00

134 lines
6.2 KiB
JSON

{
"$comment": [
"Taxonomy register for the `open/` organisation (D4: central, one file).",
"The class is READ OFF the catalog and the remotes — it is structural, not a judgement.",
"Refresh the `repos` name set against ground truth with:",
" node scripts/repo-standard-check.mjs --refresh",
"which enumerates /api/v1/orgs/open/repos (ONE call — the listing carries",
"description and topics too; per-repo fetching trips the rate limiter).",
"Enumerate, never glob: 12 of these sit at depth 2 locally, one has a",
"basename that differs from its repo name, and `.profile` is hidden."
],
"org": "open",
"forge": "https://git.fromaitochitta.com",
"marketplace": {
"name": "ktg-plugin-marketplace",
"url": "https://git.fromaitochitta.com/open/ktg-plugin-marketplace.git"
},
"repos": {
"llm-security": "plugin",
"config-audit": "plugin",
"voyage": "plugin",
"linkedin-studio": "plugin",
"graceful-handoff": "plugin",
"ai-psychosis": "plugin",
"ms-ai-architect": "plugin",
"okr": "plugin",
"human-friendly-style": "plugin",
"claude-design": "plugin",
"repo-mailbox": "plugin",
"repo-standard": "plugin",
"ktg-plugin-marketplace": "catalog",
"playground-design-system": "shared-asset",
".profile": "org-profile",
"portfolio-optimiser": "standalone",
"portfolio-optimiser-claude": "standalone",
"llm-ingestion-pipeline-security": "standalone",
"llm-ingestion-okf": "standalone"
},
"$comment_non_repos": [
"Names that LOOK like repo names and are not. These exist so that",
"'no match' and 'match on something that is not a repo' are DIFFERENT",
"outcomes — if they share an outcome, the loss goes silent, which is the",
"defect class this whole standard exists to catch.",
"Each entry is a measured false positive, not a guess."
],
"non_repos": {
"coord": "Retired repo name, deliberately still alive in prose: the CLI (coord-send), the mailbox root (~/.claude/coord/) and CLAUDE_COORD_DIR kept it — they are the transport protocol, not the product. The repo has been `repo-mailbox` since v0.3.0.",
"_broadcast": "Reserved engine namespace in the coord mailbox (`~/.claude/coord/_broadcast/`). Occupies a repo-shaped PATH position; `_` prefixed names are refused as repo identities.",
"llm-ingestion-guard": "Package name published by `llm-ingestion-pipeline-security`. A package, not a repo.",
"claude-code-llm-security": "Pre-split name of `llm-security`. This one IS dead — the org's only rename produced every dead reference we found. Listed so the finding names the successor instead of just failing."
},
"$comment_classes": [
"Per class: required files, required README headings, and the install form.",
"A flat standard across all classes would demand a ROADMAP from a 5-line",
"profile. ROADMAP is deliberately absent everywhere: it is 0/18 today and is",
"drafted from STATE by a human. A gate that fails every repo teaches people",
"to switch the gate off.",
"",
"CONTRIBUTING.md, CODE_OF_CONDUCT.md and MAINTAINERS.md are deliberately NOT",
"required anywhere. The maintainer works alone and the catalog's published",
"stance already says so — 'solo-maintained, fork-and-own; issues welcome as",
"signals, pull requests not accepted'. Contributor-facing documentation for a",
"project that accepts no contributors is theatre, and a CODE_OF_CONDUCT with",
"an unattended placeholder address is worse than none: it is a visible",
"unfinished template. This is NOT a rule against having them — files already",
"present are a separate cleanup decision, not a gate finding.",
"",
"Consumer-facing documentation is unaffected by working alone, and that is",
"the whole distinction: SECURITY.md, LICENSE, CHANGELOG, non-goals and honest",
"limitations exist for the reader, not for a contributor."
],
"classes": {
"plugin": {
"required_files": ["README.md", "LICENSE", "CHANGELOG.md", ".claude-plugin/plugin.json"],
"required_headings": ["## Install", "## Non-goals", "## Changelog"],
"install": "plugin"
},
"catalog": {
"required_files": ["README.md", "LICENSE", "GOVERNANCE.md", "CONVENTIONS.md", ".claude-plugin/marketplace.json"],
"required_headings": ["## Install", "## Non-goals"],
"install": "catalog"
},
"shared-asset": {
"required_files": ["README.md", "LICENSE"],
"required_headings": ["## Non-goals"],
"install": "vendor"
},
"org-profile": {
"required_files": ["README.md"],
"required_headings": [],
"install": "none"
},
"standalone": {
"required_files": ["README.md", "LICENSE"],
"required_headings": ["## Install", "## Non-goals"],
"install": "package"
}
},
"$comment_traits": [
"A SECOND axis, orthogonal to class. Class is structural (read off the",
"catalog and the remotes); a trait is about what the code DOES, which no",
"remote can tell you. `security` attaches the obligations a tool acquires by",
"handling untrusted input: a real disclosure channel, and limitations stated",
"with their mechanism.",
"",
"PROPOSED BY THE GATE'S AUTHOR, NOT MEASURED — the operator owns this list.",
"Marking a repo `security` decides that it owes a SECURITY.md, so adding or",
"removing a name here is a judgement, not a reading. These two were picked",
"because both process untrusted input as their stated purpose."
],
"traits": {
"llm-security": ["security"],
"llm-ingestion-pipeline-security": ["security"]
},
"trait_requirements": {
"security": {
"required_files": ["SECURITY.md"],
"required_headings": ["## Known limitations"]
}
},
"description_max_codepoints": 180,
"$comment_length": [
"180 codepoints, not bytes and not UTF-16 units. The same string measures 248",
"/ 249 / 253 across the three yardsticks (graceful-handoff: `👉` is astral).",
"An em-dash costs 3 bytes but 1 codepoint AND 1 UTF-16 unit, so it exposes",
"only the outer layer and hides the inner one. JS-based tooling reads one",
"higher per astral character. Upper bound: 207 nearly filled the card's text",
"field; 220 is untested and may overflow."
]
}