diff --git a/.changeset/vivid-eagles-forage.md b/.changeset/vivid-eagles-forage.md new file mode 100644 index 000000000..87e403865 --- /dev/null +++ b/.changeset/vivid-eagles-forage.md @@ -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) diff --git a/docs/README.md b/docs/README.md index 08a22c305..76aa7f4f3 100644 --- a/docs/README.md +++ b/docs/README.md @@ -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 --- diff --git a/docs/how-to/develop-a-capability.md b/docs/how-to/develop-a-capability.md index 38cae6abe..5d374956f 100644 --- a/docs/how-to/develop-a-capability.md +++ b/docs/how-to/develop-a-capability.md @@ -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. diff --git a/docs/how-to/list-your-reviewer-lane.md b/docs/how-to/list-your-reviewer-lane.md new file mode 100644 index 000000000..0526570d8 --- /dev/null +++ b/docs/how-to/list-your-reviewer-lane.md @@ -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 ", + "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/-`, 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 diff --git a/docs/how-to/ship-a-reviewer-lane.md b/docs/how-to/ship-a-reviewer-lane.md index a874449db..335658e67 100644 --- a/docs/how-to/ship-a-reviewer-lane.md +++ b/docs/how-to/ship-a-reviewer-lane.md @@ -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. --- diff --git a/docs/registries/README.md b/docs/registries/README.md index bdf650244..de0118bdd 100644 --- a/docs/registries/README.md +++ b/docs/registries/README.md @@ -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