Skip to content
Development
Command

/distribution-vet

Maintainer-only. Classifies every file that would newly ship to adopters against the written distribution-boundary categories, withholds by default when none matches cleanly, and asks the maintainer only where the taxonomy does not settle it, so the release CLI can produce a

BOOST
From plugin
gaia-react-gaia
2313 skills13 agents13 commands
Install
$ npx -y skills add gaia-react/gaia --agent claude-code

How it fires

How this command gets triggered: by you, by Claude, or both.

  • Fires itselfClaude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/distribution-vet

Context preview

What this command does when you run it.

Maintainer-only. Classifies every file that would newly ship to adopters against the written distribution-boundary categories, withholds by default when none matches cleanly, and asks the maintainer only where the taxonomy does not settle it, so the release CLI can produce a

Command definition

distribution-vet.md
name: distribution-vet
description: Maintainer-only. Classifies every file that would newly ship to adopters against the written distribution-boundary categories, withholds by default when none matches cleanly, and asks the maintainer only where the taxonomy does not settle it, so the release CLI can produce a manifest.
disable-model-invocation: true

/distribution-vet

Maintainer-only. Thin orchestrator over `.gaia/cli/gaia-maintainer`, which owns every deterministic step. This command supplies the one thing the CLI cannot: a classification of each newly-shipping file against the written distribution boundary, and a maintainer's answer on the few the taxonomy does not settle.

`.gaia/release-exclude` is the distribution boundary: a file ships to adopters if and only if git tracks it and no line in that file masks it. `.gaia/manifest.json` is the update policy `/update-gaia` consumes, and incidentally the ledger of which shipping files a maintainer has acknowledged. A file that git tracks, that no exclude line masks, and that the manifest does not yet list is "unanswered": it would ship, but nobody has said so on purpose.

Step 1. Find the unanswered files

.gaia/cli/gaia-maintainer release manifest --check --json

`--check` is read-only. It exits non-zero whenever it finds any of five conditions, so capture stdout and parse it as JSON regardless of the exit code; a non-zero exit here is not a failure, it is the normal signal that something needs attention. The payload shape is:

{"missing": [{"expected": "owned", "file": ".gaia/statusline/example.sh"}], "extra": [], "drift": [], "regionDrift": [], "versionDrift": null}

`missing` is an array of objects, not of path strings: the path lives in `.file`, and `.expected` is the update class the classifier would assign. Extract paths with:

jq -r '.missing[].file'

Treating `missing`'s entries as if they were bare strings prints JSON blobs instead of paths and silently breaks Step 3's classification.

`missing` is not "everything that ships." The paths in `ADOPTER_OWNED_SENTINELS` (`.gaia/cli/src/release/manifest.ts`: `.gaia/manifest.json`, `.gaia/packages.json`, `.gaia/VERSION`, and `wiki/log.md`) are permanent adopter-owned fixtures that ship with baseline content but are never classified, so they never enter `missing` and this command never asks about them. That is correct, not a gap.

Step 2. Decide which path applies

  • **Nothing outstanding.** `missing` is empty and the other four conditions (`extra`, `drift`, `regionDrift`, `versionDrift`) are all empty: report that the boundary is current, write nothing, regenerate nothing, and stop. Regenerating here would rewrite the manifest's timestamp for no reason. `git status --porcelain` for `.gaia/manifest.json` and `.gaia/release-exclude` must stay empty.
  • **Bookkeeping only.** `missing` is empty but at least one of the other four conditions is not: this is accounting drift, not a boundary question, nobody needs to decide whether a file ships. Name the condition(s) that fired and list their entries, then ask the maintainer via `AskUserQuestion` whether to regenerate now to absorb them. Do not regenerate unprompted.
  • **Files await an answer.** `missing` is non-empty: continue to Step 3.

Step 3. Classify against the categories, then ask only what needs asking

`.gaia/release-exclude` carries twelve numbered categories, each with a rationale paragraph, and is the single authoritative list of what stays maintainer-only. Most of `missing` is already answered there: category 3 settles a shipped script's verification rig in one line, category 4 settles everything under `.gaia/cli/src/`, category 1 settles the `/gaia-*` command split and names the adopter-useful exceptions.

So classify first and ask second. This is not "use judgment": it is matching each file against a written taxonomy and saying which entry it matched and why. A wrong decision then surfaces as a wrong **citation**, which a reader can check against the category's own text, instead of as a verdict they would have to re-derive from scratch.

3a. Classify every path

Read the categories out of `.gaia/release-exclude`: the number, the title, and the rationale paragraph under each header. The rationale is what a path is matched against; the title alone is not enough to match on.

Then record three things for each path in `missing`:

  • the **decision**, ship or withhold;
  • the **category** it matched, by number, or `none`;
  • a **one-line reason** naming what in that category's rationale the path satisfies.

Match on the rationale a category states, never on the shape of a path's neighbours. "Its siblings are excluded" is a guess that looks like a match.

The categories are **exclusion** categories, so a match is a withhold and a ship has to come from somewhere else. Three arms, and every path takes exactly one:

  • A category's rationale **covers** the path: **withhold**, citing that category.
  • A category's rationale **exempts** the path: **ship**, citing that category and the clause that exempts it. Several categories carry such a clause, and it is written inside the rationale rather than beside the paths: a `DOES ship` note, or an "adopters receive only" sentence that names what the exclusion spares. Category 1's "Other `/gaia-*` commands (plan, handoff, pickup, audit) are adopter-useful and must NOT be added here" is the worked case. Read a category's whole rationale for such a clause before taking the first arm; a category that excludes a directory often ships something inside it.
  • **No rationale reaches the path in either direction**: record `none`, and send it to 3b's first class, the genuinely novel one.

**A path in that third arm is recorded as a withhold**, and surfaced in 3b. It is never shipped on a silent default. The asymmetry is the whole reason:

  • A wrong **ship** is corrected by an upstream deletion, and the Update Workflow's deletion table prompts the adopt
Read more
Ships withgaia-react-gaia

Claude is raw power. GAIA is order and focus. The foundation that keeps Claude-shipped code production-grade as your team scales. The React frontend is handled. You build the rest of your app on top. Every convention enforced in code.

Get the whole plugin

Other commands on gaia-react-gaia.