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
94 lines
4.2 KiB
JSON
94 lines
4.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: which files are required, and which install form the README must",
|
|
"carry. A flat standard across all classes would demand a CONTRIBUTING from a",
|
|
"CSS library that takes no contributions, and a ROADMAP from a 5-line profile.",
|
|
"ROADMAP is deliberately absent everywhere: it is 0/18 today and is step 8,",
|
|
"drafted from STATE by a human. A gate that fails every repo teaches people to",
|
|
"switch the gate off."
|
|
],
|
|
"classes": {
|
|
"plugin": {
|
|
"required_files": ["README.md", "LICENSE", "CHANGELOG.md", ".claude-plugin/plugin.json"],
|
|
"install": "plugin"
|
|
},
|
|
"catalog": {
|
|
"required_files": ["README.md", "LICENSE", "GOVERNANCE.md", "CONVENTIONS.md", ".claude-plugin/marketplace.json"],
|
|
"install": "catalog"
|
|
},
|
|
"shared-asset": {
|
|
"required_files": ["README.md", "LICENSE"],
|
|
"install": "vendor"
|
|
},
|
|
"org-profile": {
|
|
"required_files": ["README.md"],
|
|
"install": "none"
|
|
},
|
|
"standalone": {
|
|
"required_files": ["README.md", "LICENSE"],
|
|
"install": "package"
|
|
}
|
|
},
|
|
|
|
"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."
|
|
]
|
|
}
|