docs(#2915): how-to for listing a reviewer lane, and correct the stale listing section (#2917)

* docs(#2904): how-to for listing a reviewer lane in the registry

#2912 shipped the Reviewer Lane Registry, which lands in 1.9.1. Two docs
consequences.

New: docs/how-to/list-your-reviewer-lane.md. A Diataxis how-to for the
publish task -- which of the three catalogs applies (and why a runtime
carrying a reviewer body lists under its primary install shape instead),
opening the required discussion thread BEFORE the PR, the three fields
that reject entries most often (slug grammar differs from id, flags stay
kebab when the slug is snake, install/uninstall must be copy-pasteable),
regenerate-don't-hand-edit, and register-once-then-Releases. Links the
registry README for the field table rather than duplicating it -- the
spec is reference, this is the task flow.

Corrected: ship-a-reviewer-lane.md said "Listing your lane is not wired
yet" and pointed at #2904 as future work. #2906 merged at 11:25Z and
#2912 at 12:11Z, so that section shipped false the moment the registry
landed. Replaced with the publish pointer.

Indexed the new guide and the generated catalog in docs/README.md, and
added the guide to develop-a-capability.md's ecosystem list.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* docs(#2904): caveat credential-bearing configKeys in both the guide and the spec

Isolated security review found the worked entry's `configKeys:
["acme.api_key"]` modelled storing a live credential with no note on
where that value ends up.

Verified: config values are written in plaintext to
.planning/config.json (docs/CONFIGURATION.md:227 -- masking is
display-only, "that file is the security boundary"), and
planning.commit_docs defaults to true (:466). So a credential declared
that way lands in the installing user's git repository unless they have
gitignored .planning/. None of the twelve first-party lanes does this --
they own only review.models.*, host, and prompt-budget keys.

The pattern originates in docs/registries/README.md:221, shipped by
#2912, so the caveat goes on BOTH surfaces rather than only on the copy
that inherited it -- the spec's example is what future authors will read
first.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* chore(#2915): backfill changeset PR number

pr: 0 -> 2917.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: sim <sim@local>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Tom Boucher
2026-07-31 09:29:51 -04:00
committed by GitHub
parent a9aba61f89
commit 49793465d7
6 changed files with 128 additions and 4 deletions

View File

@@ -0,0 +1,5 @@
---
type: Added
pr: 2917
---
**Reviewer lanes can now be listed for discovery** — a new how-to walks lane authors through publishing to the Reviewer Lane Registry: which of the three catalogs applies, opening the required discussion thread first, the fields that reject entries most often, and why registering once means GitHub Releases become the update channel. (#2904)

View File

@@ -37,6 +37,7 @@ Language versions: [English](README.md) · [Português (pt-BR)](pt-BR/README.md)
- [Design a UI phase](how-to/design-a-ui-phase.md) — use the UI phase loop for frontend and visual work
- [Develop a Capability for GSD 1.5+](how-to/develop-a-capability.md) — add feature Capabilities, hook fragments, and registry entries
- [Ship a reviewer lane in your capability](how-to/ship-a-reviewer-lane.md) — declare a `reviewer` body so `/gsd-review` discovers, invokes, and renders your external review CLI or model endpoint
- [List your reviewer lane in the registry](how-to/list-your-reviewer-lane.md) — publish a lane you have built to the Reviewer Lane Registry so other people can find and install it
- [Add or update a host's integration](how-to/add-or-update-a-host-integration.md) — set a host's documentation-sourced `runtime.hostIntegration` axes (ADR-1239 Phase A), with the `undocumented` sentinel rule
- [Turn a capability off (and keep it off)](how-to/turn-a-capability-off.md) — disable a capability via the surface, or gate individual hooks off without removing the capability
- [Drive GSD from a tracker issue](how-to/drive-gsd-from-a-tracker-issue.md) — start a phase from a GitHub, Linear, or Jira issue
@@ -63,6 +64,7 @@ Language versions: [English](README.md) · [Português (pt-BR)](pt-BR/README.md)
- [Capability matrix](reference/capability-matrix.md) — generated catalogue of every capability's role, tier, extension points, hook kinds, and `engines.gsd`
- [Capability manifest](reference/capability-manifest.md) — the full `capability.json` schema and validation rules
- [`gsd capability` command](reference/gsd-capability-command.md) — install / update / remove / list reference for third-party capabilities
- [Reviewer Lane Registry](registries/reviewer-registry.md) — generated catalogue of third-party reviewer lanes, with their flags, transport, and install commands
---

View File

@@ -246,6 +246,7 @@ From GSD 1.6.0, capabilities are versioned (the `version` field is required in `
- **How-to** — [Version and update a capability](../how-to/version-a-capability.md): manage `version`, `engines.gsd`, and `compatVersions`; use `gsd capability update`.
- **How-to** — [Remove a capability](../how-to/remove-a-capability.md): uninstall cleanly with `gsd capability remove`, including the `--purge-data` option.
- **How-to** — [Ship a reviewer lane in your capability](../how-to/ship-a-reviewer-lane.md): declare a `reviewer` body (GSD 1.9.0+) so `/gsd-review` discovers and invokes your external review CLI or model endpoint.
- **How-to** — [List your reviewer lane in the registry](../how-to/list-your-reviewer-lane.md): publish a lane to the Reviewer Lane Registry (GSD 1.9.1+) so other people can find and install it.
- **Reference** — [Capability manifest](../reference/capability-manifest.md): all fields and validation rules for `capability.json`.
- **Reference** — [Capability matrix](../reference/capability-matrix.md): which first-party capabilities exist, their extension points, and their compatibility matrix.
- **Explanation** — [Capability trust model](../explanation/capability-trust-model.md): how declarative and executable capabilities are treated differently at install time.

View File

@@ -0,0 +1,114 @@
# How to list your reviewer lane in the registry
**Goal:** Get a reviewer lane you have built into the **Reviewer Lane Registry**, so other people can find it, install it, and give you feedback.
**Prerequisites:** A working lane in a public repository, with a tagged release. If you have not built one yet, start with [Ship a reviewer lane in your capability](ship-a-reviewer-lane.md). GSD 1.9.1 or later.
Listing is a documentation PR against `gsd-core`. There is no separate account, package publish, or approval queue — you append one JSON object, regenerate a catalog, and open a PR.
---
## Check you are aiming at the right catalog
GSD has three discoverability catalogs, and picking the wrong one costs you a review round-trip. Pick by what your capability *is*, not by what it does:
| Your capability | Catalog | Source file |
|---|---|---|
| A lane and nothing else — `role: "reviewer"`, GSD never installs into it | **Reviewer Lane Registry** | `docs/registries/reviewers.json` |
| A runtime GSD installs into, that *also* carries a `reviewer` body | Whichever matches its **primary install shape** — usually the Capability or EoS registry | `capabilities.json` / `eos.json` |
| A feature capability attaching at Loop Extension Points | Community Capability Registry | `docs/registries/capabilities.json` |
The Reviewer Lane Registry exists specifically for lanes that are **not install targets in their own right**. If your capability is a host integration that happens to review as well, it belongs under its primary shape — do not list it twice.
---
## Open the discussion thread first
The `discussion` field is **required**, so the thread has to exist before you open the PR. Doing this second is the most common way to get sent back.
Start an open-ended discussion in the **EoS Registry** category. Despite the name, that category carries threads for all three catalogs. One thread per entry; it is where upvotes, experience reports, and your follow-up live.
Keep the URL — it goes straight into the entry.
---
## Write your entry
Append **exactly one** object to `docs/registries/reviewers.json`:
```json
{
"id": "acme-review-lane",
"name": "Acme Review Lane",
"type": "reviewer",
"repo": "some-org/gsd-lane-acme",
"description": "Adds an Acme-hosted model as an external reviewer lane for /gsd-review, evaluating diffs against Acme's static-analysis findings.",
"author": "Some Org <hello@some-org.example>",
"license": "MIT",
"enginesGsd": ">=1.9.1",
"install": "gsd capability install https://github.com/some-org/gsd-lane-acme.git#v1.0.0",
"uninstall": "gsd capability remove acme-review-lane",
"interactions": {
"slug": "acme",
"flags": ["--acme"],
"transport": "openai-http",
"evidenceClass": "diff-only",
"reviewsSection": "## Acme Review",
"requiresBinaries": [],
"configKeys": ["acme.api_key"],
"runtimeCompat": ["all"]
},
"discussion": "https://github.com/open-gsd/gsd-core/discussions/1236"
}
```
Three fields reject entries more often than the rest, so check them before anything else:
- **`interactions.slug`** must equal your manifest's `reviewer.slug` and follows the *lane* grammar `^[a-z0-9][a-z0-9_-]*$` — underscores and a leading digit are allowed (`lm_studio`, `4o-mini`). This is **not** the same grammar as the top-level `id`, which is kebab-only.
- **`interactions.flags`** are kebab even when the slug is snake: `lm_studio` → `--lm-studio`. Each must match `^--[a-z0-9][a-z0-9-]*$`.
- **`install`** and **`uninstall`** must be exact and copy-pasteable. Someone will paste them verbatim; a placeholder that does not run is the one thing a directory cannot tolerate.
**If a `configKeys` entry holds a live credential, say so in your README.** The example above declares `acme.api_key` to show the shape, and that shape has a consequence worth understanding before you copy it. Config values are written **in plaintext** to `.planning/config.json` — masking applies to display only, and that file is the security boundary. `planning.commit_docs` defaults to `true`, so unless the installing user has gitignored `.planning/`, a credential stored that way lands in their repository. None of the twelve first-party lanes stores a credential this way; they own only `review.models.*`, host, and prompt-budget keys. If your lane genuinely needs a secret, document the exposure for your users rather than leaving them to discover it — and never invent your own storage side-channel to route around it.
Everything else follows the shared entry shape. For the complete field-by-field table, see the [registry specification](../registries/README.md#reviewer-entries-reviewersjson-type-reviewer).
---
## Regenerate the catalog
Never hand-edit `docs/registries/reviewer-registry.md` — it is generated, and a drift gate will fail your PR:
```bash
npm run gen:registry
```
Commit **both** the JSON source and the regenerated markdown.
---
## Open the PR
Branch as `docs/<issue#>-<slug>`, and use the [registry-entry PR template](../../.github/PULL_REQUEST_TEMPLATE/registry-entry.md).
**One entry, one PR.** Do not bundle additions, updates, or removals together.
A maintainer checks one thing: whether the entry is a real, linkable solution with every required field present. It is not a quality review — inclusion is explicitly [not an endorsement](../registries/README.md#non-endorsement-stance), and entries are removed only for illegal content, malware, spam, or a dead link. Nobody will reject your lane for design decisions they would have made differently.
---
## Ship new versions without touching the registry
**Register once.** Your GitHub Releases are the update channel from then on.
Each entry embeds a live shields.io badge and a permalink to your repository's latest release, rendered directly by GitHub's markdown viewer. Cutting `v1.1.0` updates what visitors see with no follow-up PR.
The one thing worth revisiting is `enginesGsd` — if a later version of your lane starts depending on a newer GSD, update that range so the catalog does not advertise compatibility you no longer support.
---
## Related
- [Ship a reviewer lane in your capability](ship-a-reviewer-lane.md) — build the lane you are listing
- [Registry specification](../registries/README.md) — the full entry schema, non-endorsement stance, and removal policy
- [Reviewer Lane Registry](../registries/reviewer-registry.md) — the generated catalog itself
- [Publish a capability](publish-a-capability.md) — versioning, `engines.gsd`, and distribution

View File

@@ -160,13 +160,13 @@ Two naming rules are easy to conflate, so keep them apart. Your `slug` may not b
An *unknown* field inside your `reviewer` body behaves differently: it is a non-fatal warning on stderr, never a build failure. A manifest built against a newer GSD degrades visibly instead of crashing.
### Listing your lane is not wired yet
### Publish it so people can find it
You can build, install, and run a third-party lane today. You cannot yet **list** it in a discoverability catalog, and it is better to know that before you write the entry than after.
From GSD 1.9.1, a lane has its own discoverability catalog: the [Reviewer Lane Registry](../registries/reviewer-registry.md). Listing is a documentation PR — append one entry to `docs/registries/reviewers.json`, regenerate, open a PR. Register once; your GitHub Releases are the update channel from then on.
Neither existing registry accepts a lane. A [Community Capability Registry](../registries/capability-registry.md) entry requires a non-empty `loopExtensionPoints` and a `hookKinds` value, and a lane registers on zero loop extension points by design — the two fields are unsatisfiable rather than merely unset. The [EoS Registry](../registries/eos-registry.md) is for host integrations that embed the orchestration engine through the ADR-1239 interface, which a reviewer lane does not do.
Follow [List your reviewer lane in the registry](list-your-reviewer-lane.md) for the task flow.
Do not work around this by filing a loop extension point your lane does not use. A third `reviewer` entry type is tracked by [#2904](https://github.com/open-gsd/gsd-core/issues/2904) for a 1.9.x point release; until it lands, distribute your lane by URL and it will install and run normally.
The Reviewer Lane Registry is for lanes that are **not install targets in their own right**. If your `reviewer` body rides on a `role: "runtime"` capability, list that capability under whichever catalog matches its primary install shape instead — one entry, not two.
---

View File

@@ -197,6 +197,8 @@ Example:
| `configKeys` | yes | Federated config keys it owns (may be empty). |
| `runtimeCompat` | yes | Array of compatible runtimes; `["all"]` is allowed. |
> **Credential-bearing `configKeys` carry an exposure the example below does not show.** Config values are written in plaintext to `.planning/config.json` — masking is display-only, and that file is the security boundary — while `planning.commit_docs` defaults to `true`. A key holding a live credential therefore lands in the installing user's repository unless they have gitignored `.planning/`. No first-party reviewer lane stores a credential this way. If yours must, document the exposure in your own README.
Example:
```json