repo-standard/register/repos.json
Kjell Tore Guttormsen fe0d039de2 feat(register): a decided YES about tag history, and app-creator registered
Two changes that belong together: both are the register learning to record a
decision the engine could otherwise only re-report forever.

`tags_lightweight_accepted` — TAG-ANNOTATED-HISTORY (WARN) fires on 13
historical lightweight tags in three repos. A lightweight tag is movable
without a trace and the catalog pins plugins by tag, so the finding is real.
But the only remedy for a published one is force-moving it — the exact act the
check warns about — so the WARN could never be cleared. That is the `titles`
defect one axis over: the gate could not tell "we decided this" from "nobody
looked".

Keyed on tag NAME, never a count: a count stays satisfied the moment one tag is
re-cut and a different, unaccepted one takes its place.

An accepted tag emits `TAG-ANNOTATED-ACCEPTED` at OK naming the tags — it is
not dropped. An exemption is a finding, the rule `readme_desc_match` already
follows; an exception nobody can see reads exactly like a check that silently
stopped running.

13 entries, not the 14 lightweight tags that exist. `ktg-plugin-marketplace
v7.7.2` is deliberately absent: it is that repo's NEWEST tag, the one
lightweight tag with a safe remedy, and an ERROR today. Pre-accepting it would
mean cutting v7.8.0 instead of fixing it makes the finding vanish silently.
The engine enforces this independently — the newest tag cannot be accepted
away even if named, and a test pins that.

`app-creator` → `standalone` — `--refresh` measured 22 on the forge against 21
registered. Unregistered meant zero checks against a repo published on `open/`.
The class is derived, not guessed: no `.claude-plugin/plugin.json`, absent from
the catalog, own remote on `open/` — identical in form to the four existing
`standalone`.

Measured before and after across all 21 clones, every finding code diffed:
- TAG-ANNOTATED-HISTORY 3 WARN -> 0, converted 1:1 to 3 OK. None disappeared.
- TAG-ANNOTATED unchanged at 1 ERROR (ktg-plugin-marketplace v7.7.2).
- app-creator: 1 SKIP -> 16 judged findings (3 ERROR, 2 WARN). Recorded, not
  fixed — it records, it does not fix.
- Nothing else moved.
- `--refresh`: 22/22, no divergence.

The accepted lists are claims about three OTHER repos, measured from LOCAL
clones — which is the gap REMOTE-SYNC exists to name. They go to those repos by
coord so a wrong name can be disputed.

187 tests (was 182).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015AkHEqTSr1k3HbeiHu1ggW
2026-08-12 22:24:03 +02:00

226 lines
11 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",
"app-creator": "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"
},
"$comment_tags_lightweight_accepted": [
"Where a decided YES about lightweight tag HISTORY gets written down — the",
"same job `titles` does for a README H1, one axis over. A lightweight tag is",
"movable without a trace and the catalog pins plugins by tag, so it is a",
"supply-chain property; but the only remedy for a PUBLISHED one is force-",
"moving it, which is the act the check warns about. Without this list the",
"WARN can never be cleared, and the gate says the same thing forever.",
"",
"Keyed on tag NAME, never on a count. A count stays satisfied the moment one",
"tag is re-cut and a different, unaccepted one takes its place.",
"",
"MEASURED 2026-08-12 from the LOCAL clones, not from the forge — which is",
"the very gap REMOTE-SYNC exists to name, so these are claims about three",
"OTHER repos and were sent to them by coord so a wrong name can be disputed.",
"",
"13 entries, not the 14 lightweight tags that exist. `ktg-plugin-marketplace",
"v7.7.2` is DELIBERATELY ABSENT: it is that repo's newest tag, the one",
"lightweight tag with a safe remedy (`git tag -a -f`), and it is an ERROR",
"today. Pre-accepting it would mean that cutting v7.8.0 instead of fixing it",
"makes the finding vanish silently — the cheap fix skipped and unrecorded.",
"If it ages into history un-remedied, a fresh WARN is the correct signal."
],
"tags_lightweight_accepted": {
"ktg-plugin-marketplace": ["v3.4.1", "v5.0.0", "v5.0.1", "v5.0.2", "v5.0.3", "v7.7.0", "v7.7.1"],
"llm-ingestion-okf": ["v0.2.0", "v0.3.0", "v0.3.1", "v0.3.2", "v0.4.0"],
"llm-ingestion-pipeline-security": ["v0.3.0"]
},
"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."
]
}