repo-standard/register/repos.json
Kjell Tore Guttormsen 5884a64e54 feat(register): a decided title, and an org-profile that stops lying
Three changes at the register/engine boundary, all agreed with org-ops
after census 05 and all about a check missing a place to record a
legitimate exception.

`titles`: an optional per-repo README title. Set, the H1 matches it and
is OK; unset, the WARN stands as before. A human title was already this
engine's stated position and rds-v1's prescription, but a decided YES had
nowhere to live, so the same 6 WARNs were reported three censuses running
and would have been reported forever. Five registered, each H1 read from
the repo rather than copied from the census; `ai-psychosis` deliberately
left out so the one repo where a reader cannot connect title to name
stands alone. Measured across 21 local clones: 6 WARN before, 1 after,
nothing else moved.

`readme_desc_match: false` on the org-profile class: for an ordinary repo
the README opening and the forge description describe the same subject
and equality is right; for this class they do not — the README is the
org's landing page, the forge text describes the repo. The equality is
what does not apply, not either text. Class data, not a hardcoded name,
and the exemption is RECORDED as an OK naming its reason, not dropped.
`.profile` went ERROR to 0 ERROR / 0 WARN; the same README under a plugin
class is still an ERROR.

`engineCommit`: the version names a file, only the sha names the code. A
sweep stamped 18 files 0.4.0 while four carried a 0.5.0-only finding —
feature and version bump are two commits, so the stamp lied without being
broken. Present-and-null when underivable, never absent: an absent key
means an older engine, null means this one ran without a HEAD to read.

135 to 147 tests.

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

197 lines
9.6 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",
"portfolio-optimiser-commons": "shared-asset",
"llm-security-commons": "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.",
"",
"`readme_desc_match: false` turns OFF the README-opening == forge-description",
"equality for a class. Default is on, and it is right for an ordinary repo:",
"both texts describe the SAME subject there. `org-profile` is the one class",
"where they do not — its README is the ORGANISATION's landing page and the",
"forge text describes the REPO. Both are correct about their own subject, so",
"it is the equality that does not apply, not either text. A landing page's",
"opening line also carries a markdown link, and the description field renders",
"as PLAIN TEXT: passing the check would mean putting raw markdown on a real",
"surface — trading a census ERROR for a visible defect. One member, so the",
"exemption removes coverage nowhere else."
],
"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",
"readme_desc_match": false
},
"standalone": {
"required_files": ["README.md", "LICENSE"],
"required_headings": ["## Install", "## Non-goals"],
"install": "package"
}
},
"$comment_titles": [
"Where a decided YES about a README H1 gets written down. A human title is a",
"valid choice — `docs/rds-v1.md` prescribes `1. # Title` for every class, not",
"`# repo-name` — but until this map existed the decision had nowhere to live,",
"so census 05, 06 and 07 would have reported the same 6 WARNs forever.",
"",
"Set: the H1 is compared against it and a match is OK. Unset: WARN, exactly as",
"before. That makes 'we decided this is correct' and 'nobody has looked at it'",
"two different outcomes instead of one.",
"",
"PROPOSED BY THE OPERATOR, NOT MEASURED — like `traits` and `locales`, this is",
"a judgement. The five below are not one phenomenon: `.profile` CANNOT be",
"`# .profile` (the name is Forgejo's mechanism name for the org-profile repo),",
"`llm-ingestion-guard` is not a title at all but the published package name",
"(it is in `non_repos` above for the same reason), and the three plugins are",
"one consistent product convention. Each H1 was read from the repo, not",
"copied from a census.",
"",
"`ai-psychosis` (`# Interaction Awareness`) is DELIBERATELY ABSENT: it is the",
"one where a reader cannot connect the title to the repo. Leaving it standing",
"alone is the wanted effect of registering the others."
],
"titles": {
".profile": "fromaitochitta / open",
"llm-ingestion-pipeline-security": "llm-ingestion-guard",
"linkedin-studio": "LinkedIn Studio Plugin for Claude Code",
"llm-security": "LLM Security Plugin for Claude Code",
"ms-ai-architect": "AI Architect Plugin for Claude Code"
},
"$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"]
}
},
"$comment_locales": [
"A THIRD axis, orthogonal to both class and trait. Class is structural, a",
"trait is what the code DOES — this is who the code is FOR, which is the",
"standard's own stated principle: who the reader is decides what is",
"required. English is the default and is not listed. A repo aimed ONLY at a",
"Norwegian readership is `nb`, and is then WRONG in English, not right.",
"",
"PROPOSED BY THE OPERATOR, NOT MEASURED — like `traits`, this list is a",
"judgement and no remote can report it. Both entries below were named by",
"the operator on 2026-08-04 as Norway-only in their audience.",
"",
"Detection is a stopword-frequency comparison over prose with code stripped.",
"It answers WHICH language dominates, never whether the prose is any good."
],
"locales": {
"ms-ai-architect": "nb",
"okr": "nb"
},
"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."
]
}