From 5a49d52fe9c8af1dc8319877d2ad67267da3ac36 Mon Sep 17 00:00:00 2001 From: Gio Della-Libera Date: Sat, 4 Jul 2026 14:53:13 -0700 Subject: [PATCH 01/26] RFC: CLI catalog overlay --- rfcs/0010-cli-catalog-overlay.md | 483 +++++++++++++++++++++++++++++++ 1 file changed, 483 insertions(+) create mode 100644 rfcs/0010-cli-catalog-overlay.md diff --git a/rfcs/0010-cli-catalog-overlay.md b/rfcs/0010-cli-catalog-overlay.md new file mode 100644 index 00000000..9fb99952 --- /dev/null +++ b/rfcs/0010-cli-catalog-overlay.md @@ -0,0 +1,483 @@ +--- +title: CLI Catalog Overlay for AI-Routable Surfaces +authors: + - Gio +created: 2026-07-04 +last_updated: 2026-07-05 +status: draft +issue: +rfc_pr: +--- + +# Proposal: CLI Catalog Overlay for AI-Routable Surfaces + +## Summary + +Create one read-only catalog view over existing OpenClaw command and tool +surfaces so different consumers can inspect the same normalized inventory +through scoped lenses. The first implementation makes static CLI descriptors, +command-route policy, routed operations, runtime-registered Commander commands, +plugin CLI descriptors, and explicit agent/tool surfaces visible through a +single source-labeled catalog. It then derives separate prompt, audit, coverage, +and operator lenses from that catalog instead of making every consumer parse the +same giant view. + +The catalog overlay is metadata only. It does not add a new execution +dispatcher, runtime hook, gateway plugin, policy engine, or expression language. +Selected commands and tools continue to own validation, permissions, +confirmation, execution, and results. + +## Motivation + +OpenClaw has several prompt-like operational surfaces that already map to +bounded commands or tools: session status, process control, gateway operations, +skill proposal lifecycle, delegation, config updates, exports, diagnostics, and +similar command surfaces. Today those flows are often described to the model as +conversation text even when the correct behavior is already finite. + +That creates three problems: + +- the model can phrase or sequence the operation incorrectly +- the operation contract is harder to audit and test +- repeated flows consume prompt space restating bounded behavior already present + in command metadata + +The goal is not primarily token reduction. The bigger win is removing ambiguity +from actions that already have fixed contracts and already exist as commands or +tools. + +## Goals + +- Let the AI choose an existing command or tool surface from reviewable + metadata. +- Keep the selected surface responsible for validation, permissions, + confirmation, execution, and output. +- Keep prompt-facing metadata lean enough to avoid turning the catalog into a + large prompt tax. +- Provide a programmatic and CLI-readable list of OpenClaw command/tool surfaces + for maintainers and operators. +- Distinguish static descriptors, route-policy entries, explicit overlay + entries, runtime-registered commands, and plugin descriptor entries with + source/discovery metadata. +- Generate scoped lenses from the same inventory for prompts, audit/policy + review, smoke coverage, and operator handoffs. +- Add drift guards so descriptor-backed entries, list output, prompt projection, + and consumer lenses stay aligned. + +## Non-Goals + +- Replacing open-ended reasoning, code review, design review, or + troubleshooting. +- Turning every prompt into a DSL. +- Adding a general-purpose expression language. +- Encoding product judgment or policy enforcement into the catalog itself. +- Adding a new execution surface, dispatcher, runtime hook, or gateway plugin. +- Requiring skill authors or command owners to learn a new authoring format in + the first pass. +- Exposing this as a public plugin SDK contract in the first implementation. + +## Proposal + +Start with a hierarchical, additive catalog over existing registries instead of +a second command registry. The first list is structured as: + +- `cli.descriptors`: the existing top-level/core and sub-CLI descriptor + inventory. In the prototype this is 56 descriptors. +- `cli.commandRoutes`: the existing command-path routing and startup-policy + registry. In the prototype this is 93 command routes. +- `cli.routedOperations`: the mechanical fast-path route IDs derived from the + command-route registry and routed-command definitions. In the prototype this + is 14 routed operations. +- `agentToolSurfaces`: explicit metadata for tool-backed or non-CLI surfaces + that the AI also needs for routing. In the prototype this is 5 surfaces. +- `cli.runtimeCommands`: optional entries discovered from the currently + registered Commander tree for this invocation. +- `cli.pluginCommands`: optional plugin CLI descriptor entries, source-labeled + by plugin ID and only included when explicitly requested or already available + to the caller. +- `promptProjection`: a compact model-facing subset derived from routed + operations, prompt-visible agent/tool surfaces, and explicitly prompt-enabled + plugin entries. In the static prototype this is 19 prompt items. + +The explicit agent/tool surface metadata covers: + +- `skill_workshop` - manage durable skill proposal lifecycle. +- `session_status` - report current session state and model-use status. +- `sessions_spawn` - delegate work to a sub-agent or ACP session. +- `process` - inspect and manage active exec/process work. +- `gateway` - inspect, reconfigure, or restart the OpenClaw Gateway. + +Each surface entry declares: + +- `id` +- `title` +- `kind` +- `target` +- `source` +- `source_kind` +- `source_id` +- `discovery_mode` +- `visibility` +- `intent` +- `examples` +- `aliases` +- `owner` +- `status` +- `confidence` +- `risk` +- `confirmation` +- `effect_mode` +- `effects` +- `dispatch_mode` +- `command_hints` + +Example shape: + +```yaml +id: gateway +title: Gateway control +kind: command +dispatch_mode: hybrid +target: gateway +intent: Inspect, reconfigure, or restart the OpenClaw Gateway. +risk: medium +confirmation: true +effect_mode: mixed +command_hints: + - gateway status + - gateway restart + - gateway config.schema.lookup + - gateway config.apply +``` + +### Architecture + +The initial implementation has a normalized inventory layer plus scoped lenses: + +- CLI descriptor inventory: reads existing core and sub-CLI descriptors. +- Command-route inventory: reads the existing `cliCommandCatalog` routing and + startup-policy entries. +- Routed-operation inventory: derives route IDs and command paths from current + routed-command metadata. +- Runtime command inventory: can enumerate the currently registered Commander + tree for the active invocation, including nested commands already present. +- Plugin descriptor inventory: can project plugin CLI descriptors into catalog + entries, labeled by plugin ID and discovery mode, without making plugin + execution a new default catalog requirement. +- Agent/tool surface registry: owns complete metadata for non-CLI or tool-backed + model surfaces, including examples, aliases, risk, confirmation, effect mode, + effects, visibility, and command hints. +- Prompt lens: exposes only lean model-facing routing fields and filters by + available tools plus explicitly prompt-enabled plugin IDs. +- Audit, coverage, and operator lenses: consume the same inventory to group risk, + effect mode, route policy, coverage gaps, and handoff summaries. + +Consumers such as the prompt renderer, catalog list command/script, generated +reference docs, drift guards, audit reports, coverage reports, and operator +summaries read from those APIs instead of duplicating metadata. + +### Maintainability Model + +The catalog is designed to be easy to maintain because it is an overlay on +existing OpenClaw data structures, not a replacement for them. + +- CLI descriptors continue to come from the existing core and sub-CLI + descriptor registries. +- Command paths and startup-policy metadata continue to come from the existing + command catalog. +- Routed operations are derived from existing command-route metadata instead of + loading route runners or defining a second operation registry. +- Tool-backed and non-CLI surfaces use explicit metadata only where OpenClaw + does not already have a structured CLI descriptor to read. +- Prompt guidance, generated docs, audit reports, and future operator views all + consume catalog APIs instead of maintaining their own hardcoded lists. + +The expected maintenance path is therefore narrow: when an existing command, +route, or tool surface changes, the catalog either picks that up from the +existing registry or a focused guard points to the missing metadata update. The +catalog should not grow into a new execution system, policy engine, or parallel +source of truth. + +### Why Existing Catalogs Do Not Already Cover This + +OpenClaw already has several useful catalogs and descriptor registries, but they +serve narrower domains: + +- model catalogs describe model/provider availability +- channel and plugin catalogs describe installed or official integration + surfaces +- provider/install catalogs describe package or extension discovery +- CLI descriptors drive help output and command registration +- the command catalog drives command-path routing and startup policy +- routed-command definitions own command execution fast paths +- prompt guidance describes tool usage in prose + +Those pieces are necessary, and this proposal reuses them. What does not exist +today is one read-only view that joins them into an AI-routable operational +inventory: command descriptors, command routes, route-policy keys, routed +operation IDs, explicit tool-backed surfaces, risk/confirmation/effect metadata, +and a lean prompt projection. Without that joined view, docs, prompts, tests, +operator views, and audits either duplicate small command lists or infer intent +from prose/help output. + +This RFC therefore does not introduce "another catalog" for its own sake. It +adds the missing joined view over existing catalogs and registries, with drift +guards to keep the overlay honest. + +### Runtime Flow + +1. The catalog list API builds the full hierarchy from existing registries and + explicit agent/tool metadata. +2. The prompt renderer reads the prompt projection API, not the full catalog + list. +3. The AI identifies a routed operation or agent/tool surface by `id` or lean + metadata match. +4. The AI chooses the existing command or tool surface described by that entry. +5. The selected surface validates arguments, policy, and preconditions using + existing behavior. +6. If required, the selected surface asks for confirmation. +7. The selected command or tool performs the operation. +8. OpenClaw returns the normal command/tool result and any structured state that + surface already exposes. + +### CLI Access + +Expose the read-only operator view through: + +```bash +openclaw catalog list +openclaw catalog list --json +openclaw catalog list --markdown +``` + +The command is not an execution dispatcher. JSON output is the one-stop +structured view for humans, automation, docs, and future policy/admin consumers. +Markdown output is a concise operator view. + +### Proposed Implementation Stack + +1. Add the prompt projection API, prompt renderer, and focused tests over the + first routed-operation and agent/tool projection. +2. Expose `buildCatalogList()` as the read-only programmatic catalog list API + over CLI descriptors, command routes, routed operations, and agent/tool + surfaces. +3. Add `openclaw catalog list` plus a thin script wrapper for JSON/Markdown + output. +4. Generate an AI surface catalog docs page from the full catalog hierarchy. +5. Add guards for required metadata, descriptor alignment, prompt size, and + generated output drift. + +### Full Integration Plan + +The catalog should become the shared metadata source for mechanical OpenClaw +surfaces, not just prompt text. Integration should proceed in narrow consumers +that prove value while keeping execution with the existing command and tool +implementations. + +1. Prompt routing: keep the system prompt on the lean projection only. It should + classify bounded requests into existing routed operations or agent/tool + surfaces, then use the current command or tool path. +2. Reference docs: generate user-facing and maintainer-facing catalog docs from + `buildCatalogList()` so command inventory, route inventory, routed + operations, and agent/tool surfaces do not drift from hand-written docs. +3. Audit and policy inventory: add read-only reports that answer questions such + as "which surfaces mutate state", "which surfaces require confirmation", + "which command paths bypass config guard", and "which routes can use network + proxy bypass". These reports should consume catalog metadata and existing + policy data; they should not enforce policy themselves. +4. Test matrix generation: derive smoke-test candidates from `cli.routedOperations` + and command paths. The generated matrix should identify missing coverage for + mechanical routes without replacing the route implementations. +5. Operator and admin views: expose the same structured data to diagnostics, + debug views, and future admin surfaces so operators can inspect what OpenClaw + can do mechanically without scraping help output. +6. Drift guards: keep compatibility checks around descriptor presence, + route-definition alignment, generated docs, prompt projection size, and + catalog JSON shape. Counts can be checked as inventory snapshots, while + schema and ID stability should be checked more strictly. +7. Future automation adapters: if later work needs automation beyond prompt + routing, build adapters that select a catalog entry and call the existing + command or tool implementation. Do not introduce a new catalog dispatcher + until a concrete consumer proves that the existing command/tool invocation + path is insufficient. + +### Proposed PR Plan + +Because the catalog's value is the combination of normalized inventory plus +consumer-specific lenses, the first implementation stack should prove the full +vertical slice rather than landing only a static list first. + +1. Foundation: normalized catalog inventory + - Deliverables: `buildCatalogList()`, `openclaw catalog list`, static core + and sub-CLI descriptors, command-route policy entries, routed operations, + explicit agent/tool surfaces, schema version, source/discovery metadata, + visibility metadata, startup-policy entry, script wrapper, and drift guards. + - Scenario: `openclaw catalog list --json` shows static OpenClaw command and + tool surfaces in one source-labeled shape. + - Non-goal: no new dispatcher and no policy enforcement. + - Acceptance: static catalog counts are deterministic; descriptors/routes are + source-labeled; JSON/Markdown output is parseable and proxy-safe. + +2. Runtime command lens + - Deliverables: Commander-tree enumeration for commands registered in the + current invocation, including nested subcommands already loaded in the + runtime command tree. + - Scenario: an operator can ask what commands OpenClaw has actually + registered right now instead of only seeing static descriptor placeholders. + - Non-goal: do not force-load command trees just to discover them. + - Acceptance: runtime entries are labeled `runtime-registered` and can be + passed into the catalog without changing static catalog output. + +3. Plugin descriptor lens + - Deliverables: plugin CLI descriptors projected into catalog command entries + with `source_kind=plugin`, plugin ID, command path, and discovery mode. + - Scenario: a plugin can contribute command metadata that appears in catalog + output without hand-editing prompt prose or core command lists. + - Non-goal: do not make the default catalog command execute arbitrary plugin + code solely for discovery. + - Acceptance: plugin descriptor entries are opt-in or caller-supplied, + source-labeled, and not prompt-visible unless a prompt lens explicitly + enables that plugin. + +4. Prompt lens + - Deliverables: lean prompt projection, prompt renderer, available-tool + filtering, prompt budget guard, and explicit opt-in for plugin descriptor + commands that are allowed into prompt scope. + - Scenario: the AI sees the small set of surfaces available in its current + scope, including eligible plugin surfaces, without seeing the full audit or + operator inventory. + - Non-goal: do not dump the full catalog into the prompt. + - Acceptance: prompt projection remains small, filters unavailable tools, and + only includes plugin entries when a trusted/allowed plugin ID is supplied. + +5. Audit, coverage, and operator lenses + - Deliverables: read-only `catalog audit`, `catalog test-matrix`, and + `catalog summary` outputs for risk/effect/confirmation grouping, route + policy keys, smoke coverage gaps, and compact operator/admin handoffs. + - Scenario: maintainers can inspect static, runtime, plugin, route, and tool + surfaces by the lens that matches their job: audit/policy review, coverage + planning, or operator handoff. + - Non-goal: do not fail CI or enforce policy from these reports in the first + stack. + - Acceptance: each lens is deterministic, covered by focused tests, and + consumes catalog data rather than prompt text or hand-maintained lists. + +After that first vertical slice lands, the next stack should harden the catalog +as a reusable integration surface without turning it into a dispatcher or policy +engine. + +6. Stable JSON schema fixtures + - Deliverables: checked fixtures for `catalog list`, `catalog audit`, + `catalog test-matrix`, `catalog summary`, and prompt projection output. + Fixtures should lock schema versions, stable IDs, required fields, and + value kinds while treating inventory counts as expected-to-change + snapshots. + - Scenario: maintainers can review catalog contract changes intentionally + instead of discovering JSON-shape drift through downstream consumers. + - Non-goal: do not freeze every command count as a compatibility promise. + - Acceptance: fixture checks fail on removed/renamed fields, unstable IDs, or + schema-version drift, but allow deliberate inventory count updates. + +7. Generated reference docs for all lenses + - Deliverables: generated docs for `catalog list`, `catalog audit`, + `catalog test-matrix`, `catalog summary`, runtime entries, plugin entries, + and prompt scope. + - Scenario: users and maintainers can inspect the catalog surfaces from docs + generated by the same APIs used by automation. + - Non-goal: do not hand-write parallel catalog tables. + - Acceptance: docs generation has a `--check` mode and consumes catalog APIs + rather than prompt text. + +8. Deeper runtime and plugin enumeration + - Deliverables: richer runtime and plugin metadata where OpenClaw can collect + it without force-loading arbitrary plugin runtime code, including clearer + source labels, parent paths, hidden-command filtering, and metadata-only + plugin behavior. + - Scenario: audit and operator consumers can tell static descriptors, + currently registered commands, and plugin-provided descriptors apart. + - Non-goal: do not execute plugin registrars or arbitrary plugin runtime code + only to make the catalog look complete. + - Acceptance: runtime/plugin entries remain source-labeled, metadata-only + plugin loading is JSON-safe, and hidden/private commands stay out of + public lenses. + +9. Advisory CI and report integration + - Deliverables: non-blocking catalog summary and test-matrix artifacts for + PRs, with coverage-gap and drift summaries that maintainers can inspect. + - Scenario: a PR touching command routes, descriptors, prompts, or tools can + see catalog impact without making the first reports hard gates. + - Non-goal: do not fail normal CI on catalog coverage gaps until maintainers + choose specific gate semantics. + - Acceptance: reports are deterministic, easy to attach to PR validation, + and clearly labeled advisory. + +10. Policy/admin consumer contract + - Deliverables: a stable import path and minimal data contract for policy, + diagnostics, and future admin consumers, plus guidance on which fields are + stable contracts versus inventory snapshots. + - Scenario: policy/admin code can consume catalog metadata without scraping + help output or coupling to prompt-rendering internals. + - Non-goal: do not add enforcement, conditional enablement, or a new + catalog execution path. + - Acceptance: consumer-facing exports are documented, tested, and scoped to + read-only metadata. + +## Rationale + +This design uses OpenClaw's existing command registration and tool contracts as +the source of truth. That keeps the overlay small and reviewable while avoiding +a second control plane. + +The main alternative is to create a typed operation or DSL layer. That would +make bounded operations explicit, but it would also create a new surface that +could drift from current CLI/tool behavior. Starting from the CLI descriptor +catalog is lower risk because every catalog entry must point at an existing +surface. + +The prompt projection and catalog list APIs are intentionally separate. The +catalog list is one-stop shopping for structured metadata. The prompt needs only +a compact routing view. Separating them avoids prompt scraping while keeping +token cost visible. + +## Evaluation Plan + +Compare current prompt-driven behavior with catalog-overlay behavior on a fixed +set of bounded tasks: + +- set or inspect session state +- approve or reject a bounded action +- add or remove an allowlist entry +- advance a wizard step +- export session or trajectory data +- install, enable, disable, or refresh a skill/plugin +- collect a diagnostic or audit bundle + +Track: + +- correctness +- retries +- clarification turns +- total tokens +- tool calls +- latency +- manual intervention +- policy violations +- audit completeness + +The overlay is better only if it is at least as safe as the current path, +reduces retries or prompt ambiguity on repeated mechanical operations, preserves +user-visible behavior, and produces a readable audit trail for covered actions. + +## Unresolved Questions + +- How much of the command-route policy should be exposed as stable metadata + instead of summarized as route policy keys? +- Should descriptor and command-route counts become explicit compatibility + guards, or should they be treated as expected-to-change inventory counts? +- Where should confirmation thresholds live? +- Are simple metadata gates enough, or is conditional enablement eventually + needed? +- Which registry and catalog list exports should be treated as stable enough + for downstream policy/admin consumers? +- Where should future policy/admin consumers import catalog list data from so + they do not couple to prompt rendering internals? From 9985fd3fe90b836ca2000fa5615e0803b41e963e Mon Sep 17 00:00:00 2001 From: Gio Della-Libera Date: Sun, 5 Jul 2026 14:36:21 -0700 Subject: [PATCH 02/26] Update CLI catalog RFC learnings --- rfcs/0010-cli-catalog-overlay.md | 58 ++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 14 deletions(-) diff --git a/rfcs/0010-cli-catalog-overlay.md b/rfcs/0010-cli-catalog-overlay.md index 9fb99952..8d96a240 100644 --- a/rfcs/0010-cli-catalog-overlay.md +++ b/rfcs/0010-cli-catalog-overlay.md @@ -381,18 +381,23 @@ engine. 7. Generated reference docs for all lenses - Deliverables: generated docs for `catalog list`, `catalog audit`, `catalog test-matrix`, `catalog summary`, runtime entries, plugin entries, - and prompt scope. + and prompt scope, plus docs-map and i18n glossary updates where the + generated page participates in the normal docs index. - Scenario: users and maintainers can inspect the catalog surfaces from docs generated by the same APIs used by automation. - Non-goal: do not hand-write parallel catalog tables. - - Acceptance: docs generation has a `--check` mode and consumes catalog APIs - rather than prompt text. + - Acceptance: docs generation has a `--check` mode, consumes catalog APIs + rather than prompt text, produces exactly the checked-in formatting, and + keeps public docs deterministic even when local/private QA CLI flags are + enabled. 8. Deeper runtime and plugin enumeration - Deliverables: richer runtime and plugin metadata where OpenClaw can collect it without force-loading arbitrary plugin runtime code, including clearer source labels, parent paths, hidden-command filtering, and metadata-only - plugin behavior. + plugin behavior. Hidden/private descriptor metadata must survive the real + plugin registry and captured-registration normalization paths before any + catalog lens filters it. - Scenario: audit and operator consumers can tell static descriptors, currently registered commands, and plugin-provided descriptors apart. - Non-goal: do not execute plugin registrars or arbitrary plugin runtime code @@ -412,15 +417,42 @@ engine. and clearly labeled advisory. 10. Policy/admin consumer contract - - Deliverables: a stable import path and minimal data contract for policy, - diagnostics, and future admin consumers, plus guidance on which fields are - stable contracts versus inventory snapshots. + - Deliverables: a documented CLI JSON contract for policy, diagnostics, and + future admin consumers, plus guidance on which fields are stable contracts + versus inventory snapshots. Source modules remain repo-internal until + OpenClaw deliberately adds package exports for them. - Scenario: policy/admin code can consume catalog metadata without scraping help output or coupling to prompt-rendering internals. - Non-goal: do not add enforcement, conditional enablement, or a new - catalog execution path. - - Acceptance: consumer-facing exports are documented, tested, and scoped to - read-only metadata. + catalog execution path, and do not promise `src/` implementation imports + as a published API. + - Acceptance: `openclaw catalog ... --json` is documented as the stable + external read path; any future import/export surface is added explicitly, + tested, and scoped to read-only metadata. + +### Review Learnings Incorporated + +The PR6-10 review pass tightened several boundaries in this RFC: + +- Checked JSON fixtures are reviewable snapshots. They should protect schema + versions, required fields, stable IDs, and value kinds, while treating counts + and inventory membership as expected-to-change catalog snapshots. +- Public generated docs must stay deterministic. They should use the public + catalog shape, participate in existing docs gates, and avoid leaking + private/local QA surfaces even when those surfaces are enabled in a developer + environment. +- Static docs and live inventory serve different jobs. Generated docs describe + the stable catalog concepts; `catalog list --json` can include runtime + Commander entries for the current invocation; plugin descriptor entries should + appear only when the caller opts into or supplies that metadata. +- Plugin metadata must be preserved before filtering. Hidden/private markers + need to survive the real registry path, not only direct unit-test fixtures. +- The external contract is CLI-first for now. Until package exports are added + deliberately, downstream consumers should rely on `openclaw catalog ... --json` + rather than importing catalog builder modules from `src/`. +- Catalog reports should start advisory. They can produce PR artifacts and + review summaries, but they should not become blocking CI gates until + maintainers choose explicit policy semantics. ## Rationale @@ -477,7 +509,5 @@ user-visible behavior, and produces a readable audit trail for covered actions. - Where should confirmation thresholds live? - Are simple metadata gates enough, or is conditional enablement eventually needed? -- Which registry and catalog list exports should be treated as stable enough - for downstream policy/admin consumers? -- Where should future policy/admin consumers import catalog list data from so - they do not couple to prompt rendering internals? +- When should OpenClaw add package exports for catalog builders instead of + keeping the external contract on `openclaw catalog ... --json`? From 85b58f22f828fd9f5ffe422ae00ccd22802dd68a Mon Sep 17 00:00:00 2001 From: Gio Della-Libera Date: Sun, 5 Jul 2026 16:48:16 -0700 Subject: [PATCH 03/26] Refocus CLI catalog RFC --- rfcs/0010-cli-catalog-overlay.md | 323 ++++++++++++++----------------- 1 file changed, 149 insertions(+), 174 deletions(-) diff --git a/rfcs/0010-cli-catalog-overlay.md b/rfcs/0010-cli-catalog-overlay.md index 8d96a240..a5415704 100644 --- a/rfcs/0010-cli-catalog-overlay.md +++ b/rfcs/0010-cli-catalog-overlay.md @@ -1,5 +1,5 @@ --- -title: CLI Catalog Overlay for AI-Routable Surfaces +title: CLI Catalog View for OpenClaw Command Surfaces authors: - Gio created: 2026-07-04 @@ -9,54 +9,63 @@ issue: rfc_pr: --- -# Proposal: CLI Catalog Overlay for AI-Routable Surfaces +# Proposal: CLI Catalog View for OpenClaw Command Surfaces ## Summary Create one read-only catalog view over existing OpenClaw command and tool -surfaces so different consumers can inspect the same normalized inventory -through scoped lenses. The first implementation makes static CLI descriptors, -command-route policy, routed operations, runtime-registered Commander commands, -plugin CLI descriptors, and explicit agent/tool surfaces visible through a -single source-labeled catalog. It then derives separate prompt, audit, coverage, -and operator lenses from that catalog instead of making every consumer parse the -same giant view. - -The catalog overlay is metadata only. It does not add a new execution -dispatcher, runtime hook, gateway plugin, policy engine, or expression language. -Selected commands and tools continue to own validation, permissions, -confirmation, execution, and results. +registries so maintainers, operators, docs, tests, and prompt routing can +inspect the same normalized inventory. The catalog does not replace those +registries. It joins static CLI descriptors, command-route policy, routed +operations, runtime-registered Commander commands, plugin CLI descriptors, and +explicit agent/tool surfaces into one source-labeled view, then derives scoped +outputs for prompt routing, audit, coverage, docs, and operator handoffs. + +The catalog view is metadata only. It does not add a new execution dispatcher, +runtime hook, gateway plugin, policy engine, or expression language. Selected +commands and tools continue to own validation, permissions, confirmation, +execution, and results. ## Motivation -OpenClaw has several prompt-like operational surfaces that already map to -bounded commands or tools: session status, process control, gateway operations, -skill proposal lifecycle, delegation, config updates, exports, diagnostics, and -similar command surfaces. Today those flows are often described to the model as -conversation text even when the correct behavior is already finite. +OpenClaw already has several bounded operational surfaces: session status, +process control, gateway operations, skill proposal lifecycle, delegation, +config updates, exports, diagnostics, and similar command or tool surfaces. +Their metadata is split across several useful registries and prose surfaces. +Today a consumer that wants to answer "what command/tool surfaces exist, where +did they come from, and which ones are safe for this context?" has to combine +CLI descriptors, command routing metadata, routed-command definitions, plugin +descriptors, tool-backed surfaces, and prompt guidance by hand. That creates three problems: -- the model can phrase or sequence the operation incorrectly -- the operation contract is harder to audit and test +- no single place lists the available command/tool surfaces with source labels + and risk metadata +- docs, tests, prompts, and audits can drift because they each infer the same + inventory differently +- model-facing guidance can phrase or sequence bounded operations incorrectly + when it relies on prose instead of structured metadata - repeated flows consume prompt space restating bounded behavior already present in command metadata -The goal is not primarily token reduction. The bigger win is removing ambiguity -from actions that already have fixed contracts and already exist as commands or -tools. +The goal is not primarily token reduction. The bigger win is a single +inspection point for existing command/tool metadata so bounded actions become +easier to inspect, document, test, audit, and route. ## Goals -- Let the AI choose an existing command or tool surface from reviewable +- Provide one read-only catalog view over existing OpenClaw command and tool + registries. +- Let prompt routing choose an existing command or tool surface from reviewable metadata. - Keep the selected surface responsible for validation, permissions, confirmation, execution, and output. - Keep prompt-facing metadata lean enough to avoid turning the catalog into a large prompt tax. - Provide a programmatic and CLI-readable list of OpenClaw command/tool surfaces - for maintainers and operators. -- Distinguish static descriptors, route-policy entries, explicit overlay + for maintainers, operators, docs, tests, audit, and future policy/admin + consumers. +- Distinguish static descriptors, route-policy entries, explicit catalog entries, runtime-registered commands, and plugin descriptor entries with source/discovery metadata. - Generate scoped lenses from the same inventory for prompts, audit/policy @@ -69,6 +78,7 @@ tools. - Replacing open-ended reasoning, code review, design review, or troubleshooting. - Turning every prompt into a DSL. +- Replacing existing CLI, route, plugin, provider, channel, or model catalogs. - Adding a general-purpose expression language. - Encoding product judgment or policy enforcement into the catalog itself. - Adding a new execution surface, dispatcher, runtime hook, or gateway plugin. @@ -89,7 +99,8 @@ a second command registry. The first list is structured as: command-route registry and routed-command definitions. In the prototype this is 14 routed operations. - `agentToolSurfaces`: explicit metadata for tool-backed or non-CLI surfaces - that the AI also needs for routing. In the prototype this is 5 surfaces. + that prompt routing and operator views also need. In the prototype this is 5 + surfaces. - `cli.runtimeCommands`: optional entries discovered from the currently registered Commander tree for this invocation. - `cli.pluginCommands`: optional plugin CLI descriptor entries, source-labeled @@ -178,7 +189,7 @@ summaries read from those APIs instead of duplicating metadata. ### Maintainability Model -The catalog is designed to be easy to maintain because it is an overlay on +The catalog is designed to be easy to maintain because it is a view over existing OpenClaw data structures, not a replacement for them. - CLI descriptors continue to come from the existing core and sub-CLI @@ -198,31 +209,32 @@ existing registry or a focused guard points to the missing metadata update. The catalog should not grow into a new execution system, policy engine, or parallel source of truth. -### Why Existing Catalogs Do Not Already Cover This +### Why Existing Registries Do Not Already Cover This OpenClaw already has several useful catalogs and descriptor registries, but they -serve narrower domains: - -- model catalogs describe model/provider availability -- channel and plugin catalogs describe installed or official integration - surfaces -- provider/install catalogs describe package or extension discovery -- CLI descriptors drive help output and command registration -- the command catalog drives command-path routing and startup policy -- routed-command definitions own command execution fast paths -- prompt guidance describes tool usage in prose +serve narrower domains. None of them is the single joined command/tool +inventory this proposal needs: + +| Existing source | What it owns today | What is missing for this use | +| --- | --- | --- | +| CLI descriptors | Help text, top-level/sub-CLI registration metadata, command descriptions | Route policy, routed-operation IDs, prompt scope, audit grouping, runtime/plugin detail | +| `cliCommandCatalog` | Command paths, startup policy, route policy keys | Descriptor details, routed-operation metadata, prompt-safe shape, plugin/runtime entries | +| Routed-command definitions | Mechanical command execution fast paths | Complete command inventory, help descriptors, audit/coverage views | +| Plugin descriptors and registries | Plugin-provided CLI metadata and installed/official integration surfaces | A joined view with core commands, route policy, prompt filtering, and audit grouping | +| Model/provider/channel catalogs | Provider, model, channel, and integration availability | OpenClaw command/tool operation inventory | +| Prompt guidance | Prose instructions for tool usage | Machine-readable source labels, stable IDs, risk/effect metadata, drift guards | Those pieces are necessary, and this proposal reuses them. What does not exist -today is one read-only view that joins them into an AI-routable operational +today is one read-only view that joins them into an operational command/tool inventory: command descriptors, command routes, route-policy keys, routed -operation IDs, explicit tool-backed surfaces, risk/confirmation/effect metadata, -and a lean prompt projection. Without that joined view, docs, prompts, tests, -operator views, and audits either duplicate small command lists or infer intent -from prose/help output. +operation IDs, explicit tool-backed surfaces, runtime/plugin entries, +risk/confirmation/effect metadata, and a lean prompt projection. Without that +joined view, docs, prompts, tests, operator views, and audits either duplicate +small command lists or infer intent from prose/help output. This RFC therefore does not introduce "another catalog" for its own sake. It adds the missing joined view over existing catalogs and registries, with drift -guards to keep the overlay honest. +guards to keep the view honest. ### Runtime Flow @@ -230,9 +242,10 @@ guards to keep the overlay honest. explicit agent/tool metadata. 2. The prompt renderer reads the prompt projection API, not the full catalog list. -3. The AI identifies a routed operation or agent/tool surface by `id` or lean - metadata match. -4. The AI chooses the existing command or tool surface described by that entry. +3. Prompt routing identifies a routed operation or agent/tool surface by `id` or + lean metadata match. +4. The model chooses the existing command or tool surface described by that + entry. 5. The selected surface validates arguments, policy, and preconditions using existing behavior. 6. If required, the selected surface asks for confirmation. @@ -250,22 +263,32 @@ openclaw catalog list --json openclaw catalog list --markdown ``` -The command is not an execution dispatcher. JSON output is the one-stop -structured view for humans, automation, docs, and future policy/admin consumers. +The command is not an execution dispatcher. JSON output is the joined structured +view for humans, automation, docs, and future policy/admin consumers. Markdown output is a concise operator view. ### Proposed Implementation Stack -1. Add the prompt projection API, prompt renderer, and focused tests over the - first routed-operation and agent/tool projection. -2. Expose `buildCatalogList()` as the read-only programmatic catalog list API - over CLI descriptors, command routes, routed operations, and agent/tool - surfaces. -3. Add `openclaw catalog list` plus a thin script wrapper for JSON/Markdown - output. -4. Generate an AI surface catalog docs page from the full catalog hierarchy. -5. Add guards for required metadata, descriptor alignment, prompt size, and - generated output drift. +The implementation should land as a small review stack that shows the catalog +view first, then layers dynamic inventory, prompt routing, drift guards, docs, +and hardening on top. + +1. Foundation catalog view: add `buildCatalogList()`, `openclaw catalog list`, + static CLI descriptors, command routes, routed operations, explicit + agent/tool surfaces, source labels, and parseable JSON/Markdown output. +2. Dynamic and operator lenses: add runtime Commander-tree entries, opt-in + plugin descriptor entries, `catalog audit`, `catalog test-matrix`, and + `catalog summary`. +3. Prompt projection: add the lean prompt-facing projection and prompt renderer + that read from the catalog rather than duplicating command prose. +4. Schema fixtures: add checked JSON fixtures that protect schema versions, + required fields, stable IDs, and value kinds while treating counts as + reviewable snapshots. +5. Generated docs: generate the catalog reference page from the same APIs, with + docs-map/i18n updates and a `--check` freshness mode. +6. Hardening: enrich runtime/plugin detail, preserve hidden/private plugin + metadata through registry normalization, write richer advisory report + artifacts, and document the CLI-first consumer contract. ### Full Integration Plan @@ -304,135 +327,79 @@ implementations. ### Proposed PR Plan Because the catalog's value is the combination of normalized inventory plus -consumer-specific lenses, the first implementation stack should prove the full -vertical slice rather than landing only a static list first. +consumer-specific lenses, the first implementation stack should show the shared +catalog view and its most important consumers without making reviewers evaluate +ten tiny PRs. -1. Foundation: normalized catalog inventory +1. Foundation catalog view - Deliverables: `buildCatalogList()`, `openclaw catalog list`, static core and sub-CLI descriptors, command-route policy entries, routed operations, explicit agent/tool surfaces, schema version, source/discovery metadata, - visibility metadata, startup-policy entry, script wrapper, and drift guards. - - Scenario: `openclaw catalog list --json` shows static OpenClaw command and - tool surfaces in one source-labeled shape. - - Non-goal: no new dispatcher and no policy enforcement. - - Acceptance: static catalog counts are deterministic; descriptors/routes are - source-labeled; JSON/Markdown output is parseable and proxy-safe. - -2. Runtime command lens - - Deliverables: Commander-tree enumeration for commands registered in the - current invocation, including nested subcommands already loaded in the - runtime command tree. - - Scenario: an operator can ask what commands OpenClaw has actually - registered right now instead of only seeing static descriptor placeholders. - - Non-goal: do not force-load command trees just to discover them. - - Acceptance: runtime entries are labeled `runtime-registered` and can be - passed into the catalog without changing static catalog output. - -3. Plugin descriptor lens - - Deliverables: plugin CLI descriptors projected into catalog command entries - with `source_kind=plugin`, plugin ID, command path, and discovery mode. - - Scenario: a plugin can contribute command metadata that appears in catalog - output without hand-editing prompt prose or core command lists. - - Non-goal: do not make the default catalog command execute arbitrary plugin - code solely for discovery. - - Acceptance: plugin descriptor entries are opt-in or caller-supplied, - source-labeled, and not prompt-visible unless a prompt lens explicitly - enables that plugin. - -4. Prompt lens + and JSON/Markdown output. + - Scenario: `openclaw catalog list --json` shows OpenClaw command and tool + surfaces in one source-labeled shape. + - Non-goal: no dispatcher, policy enforcement, or replacement registry. + - Acceptance: output is parseable, source-labeled, and derived from existing + registries wherever possible. + +2. Dynamic inventory and operator lenses + - Deliverables: runtime Commander-tree entries, opt-in plugin descriptor + entries, `catalog audit`, `catalog test-matrix`, and `catalog summary`. + - Scenario: maintainers can inspect static, runtime, plugin, route, and tool + surfaces by the lens that matches their job: live inventory, audit/policy + review, smoke coverage planning, or operator handoff. + - Non-goal: do not force-load command trees or plugin runtime code only for + discovery; do not fail CI or enforce policy from the first reports. + - Acceptance: dynamic entries are source-labeled, plugin entries are opt-in + or caller-supplied, and operator/audit outputs consume catalog data rather + than prompt text or hand-maintained lists. + +3. Prompt projection - Deliverables: lean prompt projection, prompt renderer, available-tool filtering, prompt budget guard, and explicit opt-in for plugin descriptor commands that are allowed into prompt scope. - - Scenario: the AI sees the small set of surfaces available in its current - scope, including eligible plugin surfaces, without seeing the full audit or - operator inventory. + - Scenario: the model sees the small set of surfaces available in its + current scope without seeing the full audit or operator inventory. - Non-goal: do not dump the full catalog into the prompt. - Acceptance: prompt projection remains small, filters unavailable tools, and - only includes plugin entries when a trusted/allowed plugin ID is supplied. + only includes plugin entries when an allowed plugin ID is supplied. -5. Audit, coverage, and operator lenses - - Deliverables: read-only `catalog audit`, `catalog test-matrix`, and - `catalog summary` outputs for risk/effect/confirmation grouping, route - policy keys, smoke coverage gaps, and compact operator/admin handoffs. - - Scenario: maintainers can inspect static, runtime, plugin, route, and tool - surfaces by the lens that matches their job: audit/policy review, coverage - planning, or operator handoff. - - Non-goal: do not fail CI or enforce policy from these reports in the first - stack. - - Acceptance: each lens is deterministic, covered by focused tests, and - consumes catalog data rather than prompt text or hand-maintained lists. - -After that first vertical slice lands, the next stack should harden the catalog -as a reusable integration surface without turning it into a dispatcher or policy -engine. - -6. Stable JSON schema fixtures +4. Schema fixtures - Deliverables: checked fixtures for `catalog list`, `catalog audit`, `catalog test-matrix`, `catalog summary`, and prompt projection output. - Fixtures should lock schema versions, stable IDs, required fields, and - value kinds while treating inventory counts as expected-to-change - snapshots. - Scenario: maintainers can review catalog contract changes intentionally instead of discovering JSON-shape drift through downstream consumers. - Non-goal: do not freeze every command count as a compatibility promise. - Acceptance: fixture checks fail on removed/renamed fields, unstable IDs, or schema-version drift, but allow deliberate inventory count updates. -7. Generated reference docs for all lenses - - Deliverables: generated docs for `catalog list`, `catalog audit`, - `catalog test-matrix`, `catalog summary`, runtime entries, plugin entries, - and prompt scope, plus docs-map and i18n glossary updates where the - generated page participates in the normal docs index. +5. Generated reference docs + - Deliverables: generated docs for the catalog commands and lenses, plus + docs-map and i18n glossary updates where the generated page participates in + the normal docs index. - Scenario: users and maintainers can inspect the catalog surfaces from docs generated by the same APIs used by automation. - Non-goal: do not hand-write parallel catalog tables. - - Acceptance: docs generation has a `--check` mode, consumes catalog APIs - rather than prompt text, produces exactly the checked-in formatting, and - keeps public docs deterministic even when local/private QA CLI flags are - enabled. - -8. Deeper runtime and plugin enumeration - - Deliverables: richer runtime and plugin metadata where OpenClaw can collect - it without force-loading arbitrary plugin runtime code, including clearer - source labels, parent paths, hidden-command filtering, and metadata-only - plugin behavior. Hidden/private descriptor metadata must survive the real - plugin registry and captured-registration normalization paths before any - catalog lens filters it. - - Scenario: audit and operator consumers can tell static descriptors, - currently registered commands, and plugin-provided descriptors apart. - - Non-goal: do not execute plugin registrars or arbitrary plugin runtime code - only to make the catalog look complete. - - Acceptance: runtime/plugin entries remain source-labeled, metadata-only - plugin loading is JSON-safe, and hidden/private commands stay out of - public lenses. - -9. Advisory CI and report integration - - Deliverables: non-blocking catalog summary and test-matrix artifacts for - PRs, with coverage-gap and drift summaries that maintainers can inspect. - - Scenario: a PR touching command routes, descriptors, prompts, or tools can - see catalog impact without making the first reports hard gates. - - Non-goal: do not fail normal CI on catalog coverage gaps until maintainers - choose specific gate semantics. - - Acceptance: reports are deterministic, easy to attach to PR validation, - and clearly labeled advisory. - -10. Policy/admin consumer contract - - Deliverables: a documented CLI JSON contract for policy, diagnostics, and - future admin consumers, plus guidance on which fields are stable contracts - versus inventory snapshots. Source modules remain repo-internal until - OpenClaw deliberately adds package exports for them. - - Scenario: policy/admin code can consume catalog metadata without scraping - help output or coupling to prompt-rendering internals. - - Non-goal: do not add enforcement, conditional enablement, or a new - catalog execution path, and do not promise `src/` implementation imports - as a published API. - - Acceptance: `openclaw catalog ... --json` is documented as the stable - external read path; any future import/export surface is added explicitly, - tested, and scoped to read-only metadata. + - Acceptance: docs generation has a `--check` mode, consumes catalog APIs, + preserves checked-in formatting, and keeps public docs deterministic when + private/local QA CLI flags are enabled. + +6. Hardening and consumer boundary + - Deliverables: richer runtime/plugin metadata, hidden/private plugin + metadata preservation through registry normalization, richer advisory + report artifacts, and a documented CLI-first consumer contract. + - Scenario: downstream consumers can use `openclaw catalog ... --json` and + advisory report artifacts without scraping help output or coupling to + prompt-rendering internals. + - Non-goal: do not promise `src/` implementation imports as a published API + and do not make advisory report artifacts blocking gates. + - Acceptance: runtime/plugin entries stay source-labeled, hidden/private + commands stay out of public lenses, advisory outputs remain clearly + non-blocking, and any future package export is added deliberately. ### Review Learnings Incorporated -The PR6-10 review pass tightened several boundaries in this RFC: +The implementation review pass tightened several boundaries in this RFC: - Checked JSON fixtures are reviewable snapshots. They should protect schema versions, required fields, stable IDs, and value kinds, while treating counts @@ -457,8 +424,8 @@ The PR6-10 review pass tightened several boundaries in this RFC: ## Rationale This design uses OpenClaw's existing command registration and tool contracts as -the source of truth. That keeps the overlay small and reviewable while avoiding -a second control plane. +the source of truth. That keeps the catalog view small and reviewable while +avoiding a second control plane. The main alternative is to create a typed operation or DSL layer. That would make bounded operations explicit, but it would also create a new surface that @@ -467,14 +434,14 @@ catalog is lower risk because every catalog entry must point at an existing surface. The prompt projection and catalog list APIs are intentionally separate. The -catalog list is one-stop shopping for structured metadata. The prompt needs only -a compact routing view. Separating them avoids prompt scraping while keeping -token cost visible. +catalog list is the broad structured metadata view. The prompt needs only a +compact routing view. Separating them avoids prompt scraping while keeping token +cost visible. ## Evaluation Plan -Compare current prompt-driven behavior with catalog-overlay behavior on a fixed -set of bounded tasks: +Compare current prompt-driven behavior with catalog-view behavior on a fixed set +of bounded tasks: - set or inspect session state - approve or reject a bounded action @@ -496,10 +463,18 @@ Track: - policy violations - audit completeness -The overlay is better only if it is at least as safe as the current path, +The catalog view is better only if it is at least as safe as the current path, reduces retries or prompt ambiguity on repeated mechanical operations, preserves user-visible behavior, and produces a readable audit trail for covered actions. +Example comparisons: + +| Task | Current behavior to compare | Catalog-view behavior to validate | +| --- | --- | --- | +| Inspect Gateway status | Prompt guidance or help text points the model toward `gateway status`. | Prompt projection exposes the `gateway` surface with command hints, while `catalog list --json` shows the source and risk metadata. | +| Review command-route policy | Maintainers inspect route definitions or command catalog entries directly. | `catalog audit --json` groups command paths by route policy key and reports routes without policy keys. | +| Plan routed-operation smoke tests | Maintainers hand-map routed operations to candidate tests. | `catalog test-matrix --json` lists routed-operation smoke candidates and coverage gaps. | + ## Unresolved Questions - How much of the command-route policy should be exposed as stable metadata From 6441711b0b22c1c6628560c0d05514fa6e31477f Mon Sep 17 00:00:00 2001 From: Gio Della-Libera Date: Sun, 5 Jul 2026 17:34:22 -0700 Subject: [PATCH 04/26] Address CLI catalog RFC review questions --- rfcs/0010-cli-catalog-overlay.md | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/rfcs/0010-cli-catalog-overlay.md b/rfcs/0010-cli-catalog-overlay.md index a5415704..0619ab19 100644 --- a/rfcs/0010-cli-catalog-overlay.md +++ b/rfcs/0010-cli-catalog-overlay.md @@ -85,6 +85,8 @@ easier to inspect, document, test, audit, and route. - Requiring skill authors or command owners to learn a new authoring format in the first pass. - Exposing this as a public plugin SDK contract in the first implementation. +- Treating prompt projection as required for the catalog list, audit, docs, or + operator views to be useful. ## Proposal @@ -92,15 +94,14 @@ Start with a hierarchical, additive catalog over existing registries instead of a second command registry. The first list is structured as: - `cli.descriptors`: the existing top-level/core and sub-CLI descriptor - inventory. In the prototype this is 56 descriptors. + inventory. - `cli.commandRoutes`: the existing command-path routing and startup-policy - registry. In the prototype this is 93 command routes. + registry. - `cli.routedOperations`: the mechanical fast-path route IDs derived from the - command-route registry and routed-command definitions. In the prototype this - is 14 routed operations. + command-route registry and routed-command definitions. - `agentToolSurfaces`: explicit metadata for tool-backed or non-CLI surfaces - that prompt routing and operator views also need. In the prototype this is 5 - surfaces. + that prompt routing and operator views also need, only when no existing + structured CLI descriptor or route metadata already represents the surface. - `cli.runtimeCommands`: optional entries discovered from the currently registered Commander tree for this invocation. - `cli.pluginCommands`: optional plugin CLI descriptor entries, source-labeled @@ -108,7 +109,11 @@ a second command registry. The first list is structured as: to the caller. - `promptProjection`: a compact model-facing subset derived from routed operations, prompt-visible agent/tool surfaces, and explicitly prompt-enabled - plugin entries. In the static prototype this is 19 prompt items. + plugin entries. + +Exact counts are intentionally omitted from the contract. They are useful in +fixtures and reports as reviewable snapshots, but command inventory changes +over time and should not become a permanent compatibility promise. The explicit agent/tool surface metadata covers: @@ -118,6 +123,12 @@ The explicit agent/tool surface metadata covers: - `process` - inspect and manage active exec/process work. - `gateway` - inspect, reconfigure, or restart the OpenClaw Gateway. +These entries are the exception path, not a new parallel registry. They cover +tool-backed or non-CLI surfaces that do not already have enough structured CLI +metadata to join from existing registries. If OpenClaw later adds structured +descriptors for those surfaces, the catalog should read them from that source +instead of keeping duplicate hand-authored metadata. + Each surface entry declares: - `id` @@ -281,11 +292,15 @@ and hardening on top. `catalog summary`. 3. Prompt projection: add the lean prompt-facing projection and prompt renderer that read from the catalog rather than duplicating command prose. + This PR is intentionally separate so maintainers can review model-facing + behavior apart from the catalog list, audit, docs, and operator surfaces. 4. Schema fixtures: add checked JSON fixtures that protect schema versions, required fields, stable IDs, and value kinds while treating counts as reviewable snapshots. 5. Generated docs: generate the catalog reference page from the same APIs, with docs-map/i18n updates and a `--check` freshness mode. + This is a drift guard for a new public CLI reference, not a hand-written + docs exercise. 6. Hardening: enrich runtime/plugin detail, preserve hidden/private plugin metadata through registry normalization, write richer advisory report artifacts, and document the CLI-first consumer contract. From 53c108fc352250f7d2dd28dca9cac1c950526163 Mon Sep 17 00:00:00 2001 From: Gio Della-Libera Date: Sun, 5 Jul 2026 17:56:47 -0700 Subject: [PATCH 05/26] Address CLI catalog plugin feedback --- rfcs/0010-cli-catalog-overlay.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/rfcs/0010-cli-catalog-overlay.md b/rfcs/0010-cli-catalog-overlay.md index 0619ab19..b5b23ca9 100644 --- a/rfcs/0010-cli-catalog-overlay.md +++ b/rfcs/0010-cli-catalog-overlay.md @@ -186,9 +186,10 @@ The initial implementation has a normalized inventory layer plus scoped lenses: - Plugin descriptor inventory: can project plugin CLI descriptors into catalog entries, labeled by plugin ID and discovery mode, without making plugin execution a new default catalog requirement. -- Agent/tool surface registry: owns complete metadata for non-CLI or tool-backed - model surfaces, including examples, aliases, risk, confirmation, effect mode, - effects, visibility, and command hints. +- Agent/tool surface adapter: supplies focused metadata for non-CLI or + tool-backed model surfaces only when existing descriptors do not already have + enough structure, including examples, aliases, risk, confirmation, effect + mode, effects, visibility, and command hints. - Prompt lens: exposes only lean model-facing routing fields and filters by available tools plus explicitly prompt-enabled plugin IDs. - Audit, coverage, and operator lenses: consume the same inventory to group risk, @@ -198,6 +199,13 @@ Consumers such as the prompt renderer, catalog list command/script, generated reference docs, drift guards, audit reports, coverage reports, and operator summaries read from those APIs instead of duplicating metadata. +The first stack should demonstrate live value in more than one consumer: +`openclaw catalog list --json` for inspection, generated docs for reference +freshness, audit/test-matrix/summary outputs for maintainer review, and prompt +projection for model-facing routing. Plugin metadata remains opt-in and +metadata-only so plugin authors can make command surfaces discoverable without +the catalog executing arbitrary plugin runtime code. + ### Maintainability Model The catalog is designed to be easy to maintain because it is a view over From 231008b804f943979d306e855226ee3498708b36 Mon Sep 17 00:00:00 2001 From: Gio Della-Libera Date: Sun, 5 Jul 2026 18:34:42 -0700 Subject: [PATCH 06/26] Clarify CLI catalog metadata ownership --- rfcs/0010-cli-catalog-overlay.md | 83 ++++++++++++++++++++------------ 1 file changed, 51 insertions(+), 32 deletions(-) diff --git a/rfcs/0010-cli-catalog-overlay.md b/rfcs/0010-cli-catalog-overlay.md index b5b23ca9..65075f2e 100644 --- a/rfcs/0010-cli-catalog-overlay.md +++ b/rfcs/0010-cli-catalog-overlay.md @@ -18,8 +18,9 @@ registries so maintainers, operators, docs, tests, and prompt routing can inspect the same normalized inventory. The catalog does not replace those registries. It joins static CLI descriptors, command-route policy, routed operations, runtime-registered Commander commands, plugin CLI descriptors, and -explicit agent/tool surfaces into one source-labeled view, then derives scoped -outputs for prompt routing, audit, coverage, docs, and operator handoffs. +ownerless tool-surface adapters into one source-labeled view, then derives +scoped outputs for prompt routing, audit, coverage, docs, and operator +handoffs. The catalog view is metadata only. It does not add a new execution dispatcher, runtime hook, gateway plugin, policy engine, or expression language. Selected @@ -65,7 +66,7 @@ easier to inspect, document, test, audit, and route. - Provide a programmatic and CLI-readable list of OpenClaw command/tool surfaces for maintainers, operators, docs, tests, audit, and future policy/admin consumers. -- Distinguish static descriptors, route-policy entries, explicit catalog +- Distinguish static descriptors, route-policy entries, ownerless adapter entries, runtime-registered commands, and plugin descriptor entries with source/discovery metadata. - Generate scoped lenses from the same inventory for prompts, audit/policy @@ -99,9 +100,14 @@ a second command registry. The first list is structured as: registry. - `cli.routedOperations`: the mechanical fast-path route IDs derived from the command-route registry and routed-command definitions. -- `agentToolSurfaces`: explicit metadata for tool-backed or non-CLI surfaces - that prompt routing and operator views also need, only when no existing - structured CLI descriptor or route metadata already represents the surface. +- Catalog metadata fields on owning descriptors and routes: optional fields on + CLI descriptors, command-route entries, and plugin CLI descriptors provide + prompt, audit, operator, and docs metadata where those registries already own + the surface. +- `agentToolSurfaces`: projected tool-backed or non-CLI surfaces. Most entries + should come from the owning descriptor/route/plugin metadata; explicit + adapter entries are reserved for surfaces that do not yet have an owning + structured registry. - `cli.runtimeCommands`: optional entries discovered from the currently registered Commander tree for this invocation. - `cli.pluginCommands`: optional plugin CLI descriptor entries, source-labeled @@ -115,19 +121,22 @@ Exact counts are intentionally omitted from the contract. They are useful in fixtures and reports as reviewable snapshots, but command inventory changes over time and should not become a permanent compatibility promise. -The explicit agent/tool surface metadata covers: +The initial owner mapping is: -- `skill_workshop` - manage durable skill proposal lifecycle. -- `session_status` - report current session state and model-use status. -- `sessions_spawn` - delegate work to a sub-agent or ACP session. -- `process` - inspect and manage active exec/process work. -- `gateway` - inspect, reconfigure, or restart the OpenClaw Gateway. +- CLI descriptors own command-level catalog metadata such as `gateway`. +- Command-route entries own routed-operation metadata such as route title, + prompt risk, confirmation requirement, and command hints. +- Plugin CLI descriptors own plugin command metadata, including optional + visibility, risk, confirmation, effect mode, and command hints. +- The adapter owns only ownerless tool-backed surfaces such as + `skill_workshop`, `session_status`, `sessions_spawn`, and `process` until + OpenClaw has a structured source for them. -These entries are the exception path, not a new parallel registry. They cover -tool-backed or non-CLI surfaces that do not already have enough structured CLI -metadata to join from existing registries. If OpenClaw later adds structured -descriptors for those surfaces, the catalog should read them from that source -instead of keeping duplicate hand-authored metadata. +Explicit adapter entries are the exception path, not a new parallel registry. +They cover tool-backed or non-CLI surfaces that do not already have enough +structured metadata to join from existing registries. If OpenClaw later adds +structured descriptors for those surfaces, the catalog should read them from +that source instead of keeping duplicate hand-authored metadata. Each surface entry declares: @@ -186,10 +195,12 @@ The initial implementation has a normalized inventory layer plus scoped lenses: - Plugin descriptor inventory: can project plugin CLI descriptors into catalog entries, labeled by plugin ID and discovery mode, without making plugin execution a new default catalog requirement. -- Agent/tool surface adapter: supplies focused metadata for non-CLI or - tool-backed model surfaces only when existing descriptors do not already have - enough structure, including examples, aliases, risk, confirmation, effect - mode, effects, visibility, and command hints. +- Catalog metadata adapters on existing owners: CLI descriptors, route entries, + and plugin CLI descriptors can carry focused metadata such as examples, + aliases, risk, confirmation, effect mode, effects, visibility, and command + hints. +- Ownerless tool adapter: supplies the same metadata only for non-CLI or + tool-backed model surfaces that do not yet have an owning descriptor or route. - Prompt lens: exposes only lean model-facing routing fields and filters by available tools plus explicitly prompt-enabled plugin IDs. - Audit, coverage, and operator lenses: consume the same inventory to group risk, @@ -212,13 +223,18 @@ The catalog is designed to be easy to maintain because it is a view over existing OpenClaw data structures, not a replacement for them. - CLI descriptors continue to come from the existing core and sub-CLI - descriptor registries. + descriptor registries, with optional catalog metadata on the descriptor that + owns the command. - Command paths and startup-policy metadata continue to come from the existing - command catalog. + command catalog, with route-local catalog metadata for routed operations that + need prompt/audit/operator labels. +- Plugin command metadata lives on plugin CLI descriptors so plugin authors do + not need a second catalog registration path. - Routed operations are derived from existing command-route metadata instead of loading route runners or defining a second operation registry. -- Tool-backed and non-CLI surfaces use explicit metadata only where OpenClaw - does not already have a structured CLI descriptor to read. +- Tool-backed and non-CLI surfaces use explicit adapter metadata only where + OpenClaw does not already have a structured descriptor, route, or plugin + entry to read. - Prompt guidance, generated docs, audit reports, and future operator views all consume catalog APIs instead of maintaining their own hardcoded lists. @@ -246,7 +262,7 @@ inventory this proposal needs: Those pieces are necessary, and this proposal reuses them. What does not exist today is one read-only view that joins them into an operational command/tool inventory: command descriptors, command routes, route-policy keys, routed -operation IDs, explicit tool-backed surfaces, runtime/plugin entries, +operation IDs, ownerless tool-backed surfaces, runtime/plugin entries, risk/confirmation/effect metadata, and a lean prompt projection. Without that joined view, docs, prompts, tests, operator views, and audits either duplicate small command lists or infer intent from prose/help output. @@ -258,7 +274,8 @@ guards to keep the view honest. ### Runtime Flow 1. The catalog list API builds the full hierarchy from existing registries and - explicit agent/tool metadata. + optional catalog metadata on owning descriptors/routes/plugins, plus + ownerless tool adapters where no owning registry exists yet. 2. The prompt renderer reads the prompt projection API, not the full catalog list. 3. Prompt routing identifies a routed operation or agent/tool surface by `id` or @@ -293,8 +310,9 @@ view first, then layers dynamic inventory, prompt routing, drift guards, docs, and hardening on top. 1. Foundation catalog view: add `buildCatalogList()`, `openclaw catalog list`, - static CLI descriptors, command routes, routed operations, explicit - agent/tool surfaces, source labels, and parseable JSON/Markdown output. + static CLI descriptors with optional catalog metadata, command routes with + route-local catalog metadata, routed operations, ownerless tool adapters, + source labels, and parseable JSON/Markdown output. 2. Dynamic and operator lenses: add runtime Commander-tree entries, opt-in plugin descriptor entries, `catalog audit`, `catalog test-matrix`, and `catalog summary`. @@ -356,9 +374,10 @@ ten tiny PRs. 1. Foundation catalog view - Deliverables: `buildCatalogList()`, `openclaw catalog list`, static core - and sub-CLI descriptors, command-route policy entries, routed operations, - explicit agent/tool surfaces, schema version, source/discovery metadata, - and JSON/Markdown output. + and sub-CLI descriptors with optional catalog metadata, command-route + policy entries with route-local catalog metadata, routed operations, + ownerless adapter surfaces, schema version, source/discovery metadata, and + JSON/Markdown output. - Scenario: `openclaw catalog list --json` shows OpenClaw command and tool surfaces in one source-labeled shape. - Non-goal: no dispatcher, policy enforcement, or replacement registry. From 0c4d3076fc6af6384d303a43da0f4941772fe44f Mon Sep 17 00:00:00 2001 From: Gio Della-Libera Date: Mon, 6 Jul 2026 14:59:31 -0700 Subject: [PATCH 07/26] Simplify CLI catalog RFC framing --- rfcs/0010-cli-catalog-overlay.md | 73 ++++++++++++++------------------ 1 file changed, 32 insertions(+), 41 deletions(-) diff --git a/rfcs/0010-cli-catalog-overlay.md b/rfcs/0010-cli-catalog-overlay.md index 65075f2e..1f7ef3ff 100644 --- a/rfcs/0010-cli-catalog-overlay.md +++ b/rfcs/0010-cli-catalog-overlay.md @@ -3,7 +3,7 @@ title: CLI Catalog View for OpenClaw Command Surfaces authors: - Gio created: 2026-07-04 -last_updated: 2026-07-05 +last_updated: 2026-07-06 status: draft issue: rfc_pr: @@ -13,17 +13,16 @@ rfc_pr: ## Summary -Create one read-only catalog view over existing OpenClaw command and tool -registries so maintainers, operators, docs, tests, and prompt routing can -inspect the same normalized inventory. The catalog does not replace those -registries. It joins static CLI descriptors, command-route policy, routed -operations, runtime-registered Commander commands, plugin CLI descriptors, and -ownerless tool-surface adapters into one source-labeled view, then derives -scoped outputs for prompt routing, audit, coverage, docs, and operator -handoffs. +Add a read-only `openclaw catalog` command over existing OpenClaw command and +tool metadata so maintainers, operators, docs, tests, and prompt routing can +inspect the same normalized inventory. OpenClaw already has internal command +catalogs, descriptors, route metadata, plugin descriptors, and tool surfaces, +but it does not have a user-facing command that joins them into one structured +view. This proposal adds that missing view without replacing the existing +registries. The catalog view is metadata only. It does not add a new execution dispatcher, -runtime hook, gateway plugin, policy engine, or expression language. Selected +runtime hook, gateway plugin, policy engine, or expression language. Existing commands and tools continue to own validation, permissions, confirmation, execution, and results. @@ -32,11 +31,11 @@ execution, and results. OpenClaw already has several bounded operational surfaces: session status, process control, gateway operations, skill proposal lifecycle, delegation, config updates, exports, diagnostics, and similar command or tool surfaces. -Their metadata is split across several useful registries and prose surfaces. -Today a consumer that wants to answer "what command/tool surfaces exist, where -did they come from, and which ones are safe for this context?" has to combine -CLI descriptors, command routing metadata, routed-command definitions, plugin -descriptors, tool-backed surfaces, and prompt guidance by hand. +Their metadata is split across useful internal sources such as CLI descriptors, +`cliCommandCatalog`, routed-command definitions, plugin descriptors, and prompt +guidance. Today there is no `openclaw catalog` command that answers "what +command/tool surfaces exist, where did they come from, and which ones are safe +for this context?" That creates three problems: @@ -91,8 +90,9 @@ easier to inspect, document, test, audit, and route. ## Proposal -Start with a hierarchical, additive catalog over existing registries instead of -a second command registry. The first list is structured as: +Start with a hierarchical, additive `openclaw catalog` view over existing +registries instead of a second command registry. The first list is structured +as: - `cli.descriptors`: the existing top-level/core and sub-CLI descriptor inventory. @@ -244,32 +244,23 @@ existing registry or a focused guard points to the missing metadata update. The catalog should not grow into a new execution system, policy engine, or parallel source of truth. -### Why Existing Registries Do Not Already Cover This +### Relationship to Existing Registries -OpenClaw already has several useful catalogs and descriptor registries, but they -serve narrower domains. None of them is the single joined command/tool -inventory this proposal needs: +This is additive. OpenClaw already has internal command catalogs and descriptor +registries, but current `main` does not expose a user-facing +`openclaw catalog` command or one joined read-only inventory. -| Existing source | What it owns today | What is missing for this use | -| --- | --- | --- | -| CLI descriptors | Help text, top-level/sub-CLI registration metadata, command descriptions | Route policy, routed-operation IDs, prompt scope, audit grouping, runtime/plugin detail | -| `cliCommandCatalog` | Command paths, startup policy, route policy keys | Descriptor details, routed-operation metadata, prompt-safe shape, plugin/runtime entries | -| Routed-command definitions | Mechanical command execution fast paths | Complete command inventory, help descriptors, audit/coverage views | -| Plugin descriptors and registries | Plugin-provided CLI metadata and installed/official integration surfaces | A joined view with core commands, route policy, prompt filtering, and audit grouping | -| Model/provider/channel catalogs | Provider, model, channel, and integration availability | OpenClaw command/tool operation inventory | -| Prompt guidance | Prose instructions for tool usage | Machine-readable source labels, stable IDs, risk/effect metadata, drift guards | - -Those pieces are necessary, and this proposal reuses them. What does not exist -today is one read-only view that joins them into an operational command/tool -inventory: command descriptors, command routes, route-policy keys, routed -operation IDs, ownerless tool-backed surfaces, runtime/plugin entries, -risk/confirmation/effect metadata, and a lean prompt projection. Without that -joined view, docs, prompts, tests, operator views, and audits either duplicate -small command lists or infer intent from prose/help output. - -This RFC therefore does not introduce "another catalog" for its own sake. It -adds the missing joined view over existing catalogs and registries, with drift -guards to keep the view honest. +The closest existing source is `cliCommandCatalog`, which owns command paths, +startup policy, and route policy keys. Other sources own adjacent pieces: +sub-CLI descriptors own help and registration metadata, routed-command +definitions own mechanical fast paths, plugin descriptors own plugin CLI +metadata, and prompts/docs describe selected usage in prose. + +This RFC keeps those sources as the owners. The catalog command reads them, +adds small optional metadata where the owning source needs prompt/audit/operator +labels, and exposes joined JSON/Markdown views for docs, audit, test planning, +prompt routing, and operator review. It should not become a parallel registry or +new execution path. ### Runtime Flow From d85755a4a39abb50b1607eb1de2633aeacd96884 Mon Sep 17 00:00:00 2001 From: Gio Della-Libera Date: Wed, 8 Jul 2026 19:52:21 -0700 Subject: [PATCH 08/26] Add node-operator catalog PR7 plan --- rfcs/0010-cli-catalog-overlay.md | 113 ++++++++++++++++++++++++++++++- 1 file changed, 112 insertions(+), 1 deletion(-) diff --git a/rfcs/0010-cli-catalog-overlay.md b/rfcs/0010-cli-catalog-overlay.md index 1f7ef3ff..eab73fd5 100644 --- a/rfcs/0010-cli-catalog-overlay.md +++ b/rfcs/0010-cli-catalog-overlay.md @@ -3,7 +3,7 @@ title: CLI Catalog View for OpenClaw Command Surfaces authors: - Gio created: 2026-07-04 -last_updated: 2026-07-06 +last_updated: 2026-07-08 status: draft issue: rfc_pr: @@ -356,6 +356,54 @@ implementations. until a concrete consumer proves that the existing command/tool invocation path is insufficient. +### Node-Operator Prompt Lens + +PR7 in this series should add a node-operator prompt/catalog lens for agents +operating paired Desktop/Gateway nodes. The base catalog already lists `node` +and `nodes` as CLI descriptors, command-route entries, and runtime Commander +entries, but node operation needs a scoped prompt view rather than a dump of +every node command into every model prompt. + +This lens should answer a narrower question: when an OpenClaw agent is operating +through a paired node, which node commands are available, what arguments do they +expect, what approval boundary applies, and which commands should the model see +for the current node context? + +Evidence comes from the current `gim-home/m` node-mode command stack: + +- `gim-home/m#4045` adds node-routed MCP commands: + `mcp.help`, `mcp.invoke`, `mcp.status`, and `mcp.cancel`. +- `gim-home/m#4086` adds filesystem node commands: + `filesystem.read`, `filesystem.write`, and `filesystem.patch`. +- `gim-home/m#4088` adds browser/file-open node commands: + `browser.open` and `file.openWithDefaultApp`, plus Desktop-owned Playwright + MCP approval behavior. + +Those PRs show the catalog value beyond generic prompt routing. Each node slice +has a command name, argument shape, approval model, risk boundary, docs text, +and model-facing behavior that must stay aligned. Without a structured catalog +lens, every new node command family requires manual prompt/docs/help updates and +can drift from the actual Gateway/Desktop approval path. + +The node-operator lens should be scoped: + +- General catalog/audit views list all known `node`/`nodes` descriptors, + command routes, runtime commands, and plugin-provided node command + descriptors. +- Prompt projection includes only node commands available in the active + node-control context. +- Low-risk read/status/help commands can be prompt-visible by default in node + mode. +- Mutating or side-effecting commands such as filesystem writes, browser opens, + app/file opens, shell/system commands, or M365 actions carry risk, + confirmation, and approval-boundary metadata. +- Plugin-provided `nodes ...` commands remain opt-in and trust-scoped. + +This is still metadata-only. The selected node command continues to execute +through the existing OpenClaw/Gateway/Desktop command path, and Desktop remains +the owner of local validation, permission cards, policy, approval memory, and +runtime execution. + ### Proposed PR Plan Because the catalog's value is the combination of normalized inventory plus @@ -430,6 +478,63 @@ ten tiny PRs. commands stay out of public lenses, advisory outputs remain clearly non-blocking, and any future package export is added deliberately. +7. Node-operator prompt lens + - Deliverables: node command source metadata plus a scoped node-operator + prompt projection over MCP, filesystem, browser/file-open, and future + system/M365 node command families. + - Scenario: Scout/OpenClaw can operate a paired node with model-visible + command names, argument hints, risk, confirmation, and approval-boundary + metadata that match the Desktop/Gateway command implementation. + - Non-goal: do not execute node commands from the catalog, import Desktop + runtime code into OpenClaw catalog generation, or dump every node command + into every default prompt. + - Acceptance: node command metadata is source-labeled, prompt output is + small and context-filtered, plugin-provided node commands remain opt-in, + and audit/test-matrix reports can cite node command families and approval + boundaries. + +### PR7 Shape: Node-Operator Lens + +PR7 can be implemented as one focused PR with three internal pieces: + +1. Node command source metadata + - Deliverables: catalog metadata for node-routed command families from the + Gateway/Desktop node command source, including command ID, title, argument + hints, owner, risk, effect mode, confirmation requirement, approval kind, + and trust boundary. + - Scenario: `openclaw catalog list --json` can identify node commands such + as `mcp.invoke`, `filesystem.write`, and `browser.open` as node-operated + surfaces rather than opaque prose. + - Non-goal: do not execute node commands from the catalog and do not import + Desktop runtime code into OpenClaw catalog generation. + - Acceptance: node command metadata is source-labeled, generated or + supplied by the owning node command registry where possible, and absent + commands do not appear in prompt scope. + +2. Node-operator prompt projection + - Deliverables: a scoped prompt lens, for example + `listCliCatalogPromptSurfaces({ scope: "node-operator", ... })`, that + includes only node commands available to the active node context. + - Scenario: an OpenClaw agent operating a paired node sees how to inspect MCP + status, invoke an allowed MCP tool, read or patch workspace files, and open + browser/file targets without seeing unrelated catalog inventory. + - Non-goal: do not dump full audit metadata or every node/plugin command + into the default system prompt. + - Acceptance: prompt output is small, context-filtered, and carries enough + command/argument/risk hints for correct tool choice. + +3. Node trust/audit/test-matrix lens + - Deliverables: catalog audit/test-matrix support for node command families, + including approval kind, side-effect classification, command availability, + and smoke-test candidates. + - Scenario: maintainers can compare the OpenClaw node prompt surface against + the actual Desktop/Gateway node command stack and find missing coverage or + mismatched risk/approval metadata. + - Non-goal: do not make this a blocking CI gate until maintainers choose + explicit policy semantics. + - Acceptance: reports can cite node command families and approval boundaries + in a stable JSON shape suitable for PR review artifacts. + ### Review Learnings Incorporated The implementation review pass tightened several boundaries in this RFC: @@ -483,6 +588,8 @@ of bounded tasks: - export session or trajectory data - install, enable, disable, or refresh a skill/plugin - collect a diagnostic or audit bundle +- operate a paired node through MCP, filesystem, browser/file-open, or future + system/M365 node commands Track: @@ -507,6 +614,7 @@ Example comparisons: | Inspect Gateway status | Prompt guidance or help text points the model toward `gateway status`. | Prompt projection exposes the `gateway` surface with command hints, while `catalog list --json` shows the source and risk metadata. | | Review command-route policy | Maintainers inspect route definitions or command catalog entries directly. | `catalog audit --json` groups command paths by route policy key and reports routes without policy keys. | | Plan routed-operation smoke tests | Maintainers hand-map routed operations to candidate tests. | `catalog test-matrix --json` lists routed-operation smoke candidates and coverage gaps. | +| Operate a paired node | Prompt guidance must be manually updated as node command families are added in PRs such as `gim-home/m#4045`, `#4086`, and `#4088`. | A node-operator prompt lens exposes the available node commands, argument hints, and approval boundaries for the active node context. | ## Unresolved Questions @@ -519,3 +627,6 @@ Example comparisons: needed? - When should OpenClaw add package exports for catalog builders instead of keeping the external contract on `openclaw catalog ... --json`? +- Should the node-operator lens consume node command metadata from an exported + OpenClaw/Gateway registry, generated command descriptors, or an artifact + produced by the Desktop/Gateway node command stack? From 5014eb39118b4e80cb9cc8647d9369bf2a0f49c1 Mon Sep 17 00:00:00 2001 From: Gio Della-Libera Date: Wed, 8 Jul 2026 20:53:55 -0700 Subject: [PATCH 09/26] Fold node catalog support into CLI catalog RFC stack --- rfcs/0010-cli-catalog-overlay.md | 60 +++++++++++++++++--------------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/rfcs/0010-cli-catalog-overlay.md b/rfcs/0010-cli-catalog-overlay.md index eab73fd5..6581c54b 100644 --- a/rfcs/0010-cli-catalog-overlay.md +++ b/rfcs/0010-cli-catalog-overlay.md @@ -356,18 +356,19 @@ implementations. until a concrete consumer proves that the existing command/tool invocation path is insufficient. -### Node-Operator Prompt Lens +### Node-Operator Catalog Support -PR7 in this series should add a node-operator prompt/catalog lens for agents -operating paired Desktop/Gateway nodes. The base catalog already lists `node` -and `nodes` as CLI descriptors, command-route entries, and runtime Commander -entries, but node operation needs a scoped prompt view rather than a dump of -every node command into every model prompt. +Node/operator command metadata should be folded through the first six PRs rather +than introduced as a separate follow-up. The base catalog already lists `node` and +`nodes` as CLI descriptors, command-route entries, and runtime Commander +entries, but paired-node operation needs structured command metadata and a +scoped prompt view rather than a dump of every node command into every model +prompt. -This lens should answer a narrower question: when an OpenClaw agent is operating -through a paired node, which node commands are available, what arguments do they -expect, what approval boundary applies, and which commands should the model see -for the current node context? +This support should answer a narrower question: when an OpenClaw agent is +operating through a paired node, which node commands are available, what +arguments do they expect, what approval boundary applies, and which commands +should the model see for the current node context? Evidence comes from the current `gim-home/m` node-mode command stack: @@ -385,7 +386,7 @@ and model-facing behavior that must stay aligned. Without a structured catalog lens, every new node command family requires manual prompt/docs/help updates and can drift from the actual Gateway/Desktop approval path. -The node-operator lens should be scoped: +The node/operator catalog support should be scoped: - General catalog/audit views list all known `node`/`nodes` descriptors, command routes, runtime commands, and plugin-provided node command @@ -478,24 +479,25 @@ ten tiny PRs. commands stay out of public lenses, advisory outputs remain clearly non-blocking, and any future package export is added deliberately. -7. Node-operator prompt lens - - Deliverables: node command source metadata plus a scoped node-operator - prompt projection over MCP, filesystem, browser/file-open, and future - system/M365 node command families. - - Scenario: Scout/OpenClaw can operate a paired node with model-visible - command names, argument hints, risk, confirmation, and approval-boundary - metadata that match the Desktop/Gateway command implementation. - - Non-goal: do not execute node commands from the catalog, import Desktop - runtime code into OpenClaw catalog generation, or dump every node command - into every default prompt. - - Acceptance: node command metadata is source-labeled, prompt output is - small and context-filtered, plugin-provided node commands remain opt-in, - and audit/test-matrix reports can cite node command families and approval - boundaries. - -### PR7 Shape: Node-Operator Lens - -PR7 can be implemented as one focused PR with three internal pieces: +The node/operator work should be distributed across the six PRs: + +- PR1 foundation: define the supplied `cli.nodeCommands` list shape and its + source, availability, approval, risk, effect, argument-hint, and trust-boundary + fields. +- PR2 dynamic/operator lenses: include node command metadata in audit, + test-matrix, and operator summary views. +- PR3 prompt lens: add a scoped `node-operator` prompt projection that is + disabled by default. +- PR4 schema fixtures: snapshot representative paired-node/node-host command + records. +- PR5 generated docs: document node/operator commands as a supported dynamic + catalog family. +- PR6 hardening: carry node command fields through advisory reports and the + CLI-first consumer contract. + +### Node-Operator Shape + +The node/operator support has three internal pieces: 1. Node command source metadata - Deliverables: catalog metadata for node-routed command families from the From 6456e69e2bfce06b772111ed2af99e0a3a4d6edf Mon Sep 17 00:00:00 2001 From: Gio Della-Libera Date: Thu, 9 Jul 2026 13:33:17 -0700 Subject: [PATCH 10/26] Link CLI catalog implementation review PRs --- rfcs/0010-cli-catalog-overlay.md | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/rfcs/0010-cli-catalog-overlay.md b/rfcs/0010-cli-catalog-overlay.md index 6581c54b..a280ddb7 100644 --- a/rfcs/0010-cli-catalog-overlay.md +++ b/rfcs/0010-cli-catalog-overlay.md @@ -3,7 +3,7 @@ title: CLI Catalog View for OpenClaw Command Surfaces authors: - Gio created: 2026-07-04 -last_updated: 2026-07-08 +last_updated: 2026-07-09 status: draft issue: rfc_pr: @@ -26,6 +26,25 @@ runtime hook, gateway plugin, policy engine, or expression language. Existing commands and tools continue to own validation, permissions, confirmation, execution, and results. +## Implementation Review Links + +There is already one upstream OpenClaw draft PR with the full end-state branch: + +- Rollup implementation PR: [openclaw/openclaw#100960](https://github.com/openclaw/openclaw/pull/100960) + +For review convenience, the same work is also prepared as fork-local stacked +draft PRs. These are not asking maintainers to merge from the fork; they are a +review aid so the stack can be read one layer at a time. If maintainers prefer, +I am happy to open the same PRs against `openclaw/openclaw` separately and merge +them in order. + +- PR1 foundation: [giodl73-repo/openclaw#11](https://github.com/giodl73-repo/openclaw/pull/11) +- PR2 dynamic/operator lenses: [giodl73-repo/openclaw#12](https://github.com/giodl73-repo/openclaw/pull/12) +- PR3 prompt projection: [giodl73-repo/openclaw#13](https://github.com/giodl73-repo/openclaw/pull/13) +- PR4 schema fixtures: [giodl73-repo/openclaw#14](https://github.com/giodl73-repo/openclaw/pull/14) +- PR5 generated docs: [giodl73-repo/openclaw#15](https://github.com/giodl73-repo/openclaw/pull/15) +- PR6 hardening and consumer contract: [giodl73-repo/openclaw#16](https://github.com/giodl73-repo/openclaw/pull/16) + ## Motivation OpenClaw already has several bounded operational surfaces: session status, From ab0327f3de7cfbfd2477deef4561580f985724ef Mon Sep 17 00:00:00 2001 From: Gio Della-Libera Date: Thu, 9 Jul 2026 13:33:46 -0700 Subject: [PATCH 11/26] Record CLI catalog RFC PR --- rfcs/0010-cli-catalog-overlay.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/0010-cli-catalog-overlay.md b/rfcs/0010-cli-catalog-overlay.md index a280ddb7..ed429dd4 100644 --- a/rfcs/0010-cli-catalog-overlay.md +++ b/rfcs/0010-cli-catalog-overlay.md @@ -6,7 +6,7 @@ created: 2026-07-04 last_updated: 2026-07-09 status: draft issue: -rfc_pr: +rfc_pr: https://github.com/openclaw/rfcs/pull/32 --- # Proposal: CLI Catalog View for OpenClaw Command Surfaces From 1abe091818da280a507b2123facf10c82786973f Mon Sep 17 00:00:00 2001 From: Gio Della-Libera Date: Thu, 9 Jul 2026 14:20:12 -0700 Subject: [PATCH 12/26] Renumber CLI catalog RFC draft --- ...overlay.md => 0016-cli-catalog-overlay.md} | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) rename rfcs/{0010-cli-catalog-overlay.md => 0016-cli-catalog-overlay.md} (94%) diff --git a/rfcs/0010-cli-catalog-overlay.md b/rfcs/0016-cli-catalog-overlay.md similarity index 94% rename from rfcs/0010-cli-catalog-overlay.md rename to rfcs/0016-cli-catalog-overlay.md index ed429dd4..b188c185 100644 --- a/rfcs/0010-cli-catalog-overlay.md +++ b/rfcs/0016-cli-catalog-overlay.md @@ -45,6 +45,43 @@ them in order. - PR5 generated docs: [giodl73-repo/openclaw#15](https://github.com/giodl73-repo/openclaw/pull/15) - PR6 hardening and consumer contract: [giodl73-repo/openclaw#16](https://github.com/giodl73-repo/openclaw/pull/16) +## Draft Status And Proof + +This RFC is still a draft and should not be merged as accepted until +maintainers choose the public CLI/API boundary and the RFC lifecycle is +complete. This PR can serve as the design discussion vehicle; if maintainers +prefer a separate `maintainer-discussion` thread, that link should be added here +before acceptance. + +The linked implementation branch is also draft review material, not proof that +the RFC is already accepted. Current implementation validation is tracked on +[openclaw/openclaw#100960](https://github.com/openclaw/openclaw/pull/100960) +and includes catalog unit coverage, generated fixture checks, generated docs +checks, formatting checks, and one Codex review pass per stacked branch. Runtime +behavior proof should stay with the implementation PR because this RFC +repository only carries the design document. + +The current implementation review branch inventories: + +- 61 CLI descriptors +- 97 command routes +- 14 routed operations +- 5 explicit agent/tool surfaces +- supplied node/operator command metadata + +The audit/report layer then groups the same inventory by state-changing versus +read-only/mixed effects, confirmation-required surfaces, route policy keys, +routes missing policy keys, routed-operation smoke-test coverage gaps, +node/operator commands, and approval-required node commands. + +This is not just a static help dump. `openclaw catalog list` collects the live +Commander tree for the current invocation, and +`openclaw catalog list --plugin-descriptors` also includes plugin-provided CLI +descriptor metadata when that metadata is explicitly requested. Scout's +plugin-only container proof demonstrates why that distinction matters: the +loaded config currently exposes 13 plugins, 11 enabled plugins, 2 plugin CLI +commands, 8 plugin tools, and 23 allowed command/tool names. + ## Motivation OpenClaw already has several bounded operational surfaces: session status, From 0e505470e7b5a6c27b261692c1632d391b60015c Mon Sep 17 00:00:00 2001 From: Gio Della-Libera Date: Thu, 9 Jul 2026 14:23:39 -0700 Subject: [PATCH 13/26] Document CLI catalog field budget --- rfcs/0016-cli-catalog-overlay.md | 33 ++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/rfcs/0016-cli-catalog-overlay.md b/rfcs/0016-cli-catalog-overlay.md index b188c185..f0fc665b 100644 --- a/rfcs/0016-cli-catalog-overlay.md +++ b/rfcs/0016-cli-catalog-overlay.md @@ -82,6 +82,39 @@ plugin-only container proof demonstrates why that distinction matters: the loaded config currently exposes 13 plugins, 11 enabled plugins, 2 plugin CLI commands, 8 plugin tools, and 23 allowed command/tool names. +## Field Budget And Trim Boundary + +The field surface should be treated as part of the proposal, not incidental +implementation detail. The implementation branch currently explores several +entry kinds with different field counts: + +- descriptors: about 9 fields per entry +- command routes: about 8 fields per entry +- routed operations: about 5 fields per entry +- runtime commands: about 13 fields per entry +- plugin commands: about 17 fields per entry +- supplied node/operator commands: about 20 fields per entry +- prompt projection entries: about 9 fields per entry + +That is useful for review because it shows the catalog can serve audit, docs, +prompt, operator, and test-matrix consumers, but it should not all become the +minimum stable contract by accident. + +The minimum `catalog list --json` contract should be small: + +- identity: stable id, command path/name, and display title or description +- provenance: source kind, source id, and discovery mode +- scope: visibility/lens membership so consumers know where the entry is meant + to appear +- safety summary: risk, effect mode, and confirmation requirement when known + +Fields such as examples, aliases, command hints, effects, owner, status, +confidence, policy keys, approval kind, trust boundary, and node-specific +availability are valuable, but they should remain advisory or lens-specific +until a concrete consumer needs them. If maintainers want a narrower first PR, +the catalog should trim to the minimum contract above and leave audit/policy, +prompt, generated-docs, and node/operator detail as follow-up lenses. + ## Motivation OpenClaw already has several bounded operational surfaces: session status, From e6c0290a846a4c38cd91c5278703e8a3875a1c0e Mon Sep 17 00:00:00 2001 From: Gio Della-Libera Date: Thu, 9 Jul 2026 14:25:00 -0700 Subject: [PATCH 14/26] Clarify CLI catalog registry metadata budget --- rfcs/0016-cli-catalog-overlay.md | 35 ++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/rfcs/0016-cli-catalog-overlay.md b/rfcs/0016-cli-catalog-overlay.md index f0fc665b..d31937d5 100644 --- a/rfcs/0016-cli-catalog-overlay.md +++ b/rfcs/0016-cli-catalog-overlay.md @@ -115,6 +115,41 @@ until a concrete consumer needs them. If maintainers want a narrower first PR, the catalog should trim to the minimum contract above and leave audit/policy, prompt, generated-docs, and node/operator detail as follow-up lenses. +## Registry Metadata Budget + +The higher-risk part is not the JSON output shape; it is what gets added to +existing registries as source metadata. The current implementation branch adds: + +- `catalog?: CliCatalogMetadata` to CLI command descriptors +- `route.catalog?: CliCatalogMetadata` to routed command entries +- `catalog?: CliCatalogMetadata` to plugin CLI command descriptors +- `hidden?: boolean` to plugin CLI command descriptors so private placeholders + can stay out of generated catalog views + +`CliCatalogMetadata` currently has 17 optional fields: `id`, `title`, `kind`, +`dispatchMode`, `target`, `visibility`, `intent`, `examples`, `aliases`, +`owner`, `status`, `confidence`, `risk`, `confirmationRequired`, `effectMode`, +`effects`, and `commandHints`. + +That breadth is useful for prototyping, but the first stable registry addition +should be narrower unless maintainers explicitly want the larger bag. A trimmed +registry contract can carry only fields that are hard to infer from existing +registries: + +- `title?` +- `visibility?` +- `risk?` +- `confirmationRequired?` +- `effectMode?` +- `commandHints?` + +Everything else can be derived by the catalog builder or kept in explicit +overlay/advisory data until a consumer proves it is worth making part of the +registry contract. In particular, `id`, `kind`, `dispatchMode`, `target`, +`owner`, `status`, and `confidence` should not be accepted as registry fields +just because the prototype used them. They need a concrete consumer or should +remain generated/advisory. + ## Motivation OpenClaw already has several bounded operational surfaces: session status, From c5557ee1c8199f5f5a75630dd60f899bef5c794a Mon Sep 17 00:00:00 2001 From: Gio Della-Libera Date: Thu, 9 Jul 2026 14:30:02 -0700 Subject: [PATCH 15/26] Reframe catalog registry metadata as native hints --- rfcs/0016-cli-catalog-overlay.md | 55 ++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/rfcs/0016-cli-catalog-overlay.md b/rfcs/0016-cli-catalog-overlay.md index d31937d5..53c878e6 100644 --- a/rfcs/0016-cli-catalog-overlay.md +++ b/rfcs/0016-cli-catalog-overlay.md @@ -118,37 +118,44 @@ prompt, generated-docs, and node/operator detail as follow-up lenses. ## Registry Metadata Budget The higher-risk part is not the JSON output shape; it is what gets added to -existing registries as source metadata. The current implementation branch adds: +existing registries as source metadata. The prototype used a generic +`catalog?: CliCatalogMetadata` bag on CLI descriptors, routed command entries, +and plugin CLI descriptors. That was useful for discovery, but it is not the +right default shape for a stable OpenClaw contract. + +The better direction is to keep each existing registry native and small, then +make the catalog builder do the hard N-to-1 normalization work: + +- CLI descriptors already own `name`, `description`, `hasSubcommands`, and + `parentDefaultHelp`. They should only need missing catalog hints such as + prompt/docs visibility or safety classification when those cannot be inferred. +- Routed command entries already own `commandPath`, `exact`, route id, and + policy data. They should only need route-local safety metadata such as + `risk`, `confirmationRequired`, or `effectMode` when policy/route data cannot + express it. +- Plugin CLI descriptors already own plugin id, parent path, descriptor name, + description, and subcommand shape through the plugin registry. They should + only need plugin-native catalog hints and a hidden/private marker if generated + catalog views must omit a placeholder. +- Node/operator commands should come from the node pairing/runtime declaration, + not from a global catalog metadata bag. + +For a first stable registry contract, avoid adding a 17-field generic bag to +multiple registries. Prefer small native optional fields that map to concrete +missing facts: -- `catalog?: CliCatalogMetadata` to CLI command descriptors -- `route.catalog?: CliCatalogMetadata` to routed command entries -- `catalog?: CliCatalogMetadata` to plugin CLI command descriptors -- `hidden?: boolean` to plugin CLI command descriptors so private placeholders - can stay out of generated catalog views - -`CliCatalogMetadata` currently has 17 optional fields: `id`, `title`, `kind`, -`dispatchMode`, `target`, `visibility`, `intent`, `examples`, `aliases`, -`owner`, `status`, `confidence`, `risk`, `confirmationRequired`, `effectMode`, -`effects`, and `commandHints`. - -That breadth is useful for prototyping, but the first stable registry addition -should be narrower unless maintainers explicitly want the larger bag. A trimmed -registry contract can carry only fields that are hard to infer from existing -registries: - -- `title?` - `visibility?` - `risk?` - `confirmationRequired?` - `effectMode?` - `commandHints?` +- plugin descriptor `hidden?` -Everything else can be derived by the catalog builder or kept in explicit -overlay/advisory data until a consumer proves it is worth making part of the -registry contract. In particular, `id`, `kind`, `dispatchMode`, `target`, -`owner`, `status`, and `confidence` should not be accepted as registry fields -just because the prototype used them. They need a concrete consumer or should -remain generated/advisory. +The catalog output can still present a normalized record with ids, source +labels, ownership, dispatch mode, status, examples, and derived summaries, but +those should be derived or supplied by explicit catalog overlays rather than +forced into every source registry. This keeps the registries familiar and puts +the integration burden in the catalog layer, where it belongs. ## Motivation From 2200c1aa3b720cfc207aaf3d1a521ee92f12632c Mon Sep 17 00:00:00 2001 From: Gio Della-Libera Date: Thu, 9 Jul 2026 14:34:23 -0700 Subject: [PATCH 16/26] Name catalog source effect and exposure structs --- rfcs/0016-cli-catalog-overlay.md | 39 ++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/rfcs/0016-cli-catalog-overlay.md b/rfcs/0016-cli-catalog-overlay.md index 53c878e6..11832112 100644 --- a/rfcs/0016-cli-catalog-overlay.md +++ b/rfcs/0016-cli-catalog-overlay.md @@ -124,31 +124,42 @@ and plugin CLI descriptors. That was useful for discovery, but it is not the right default shape for a stable OpenClaw contract. The better direction is to keep each existing registry native and small, then -make the catalog builder do the hard N-to-1 normalization work: +make the catalog builder do the hard N-to-1 normalization work. The source +registry additions should be typed around the facts they actually represent: +operational effects and catalog exposure. + +```ts +type CommandEffectProfile = { + effectMode: "read" | "mutating" | "mixed"; + confirmationRequired?: boolean; + risk?: "low" | "medium" | "high"; + commandHints?: readonly string[]; +}; + +type CatalogExposure = { + visibility?: readonly ("docs" | "prompt" | "audit" | "operator" | "policy")[]; +}; +``` - CLI descriptors already own `name`, `description`, `hasSubcommands`, and - `parentDefaultHelp`. They should only need missing catalog hints such as - prompt/docs visibility or safety classification when those cannot be inferred. + `parentDefaultHelp`. They should only need missing `catalogExposure` or + `effectProfile` data when those facts cannot be inferred. - Routed command entries already own `commandPath`, `exact`, route id, and - policy data. They should only need route-local safety metadata such as - `risk`, `confirmationRequired`, or `effectMode` when policy/route data cannot - express it. + policy data. They should only need route-local `effectProfile` data when + policy/route data cannot express it. - Plugin CLI descriptors already own plugin id, parent path, descriptor name, description, and subcommand shape through the plugin registry. They should - only need plugin-native catalog hints and a hidden/private marker if generated - catalog views must omit a placeholder. + only need plugin-native `catalogExposure`, `effectProfile`, and a + hidden/private marker if generated catalog views must omit a placeholder. - Node/operator commands should come from the node pairing/runtime declaration, not from a global catalog metadata bag. For a first stable registry contract, avoid adding a 17-field generic bag to -multiple registries. Prefer small native optional fields that map to concrete +multiple registries. Prefer small native optional structs that map to concrete missing facts: -- `visibility?` -- `risk?` -- `confirmationRequired?` -- `effectMode?` -- `commandHints?` +- `effectProfile?` +- `catalogExposure?` - plugin descriptor `hidden?` The catalog output can still present a normalized record with ids, source From 4429c7003304fc7cb953f72b7077a8f84ca1c8fe Mon Sep 17 00:00:00 2001 From: Gio Della-Libera Date: Thu, 9 Jul 2026 14:39:55 -0700 Subject: [PATCH 17/26] Align catalog exposure terminology --- rfcs/0016-cli-catalog-overlay.md | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/rfcs/0016-cli-catalog-overlay.md b/rfcs/0016-cli-catalog-overlay.md index 11832112..4900a9b1 100644 --- a/rfcs/0016-cli-catalog-overlay.md +++ b/rfcs/0016-cli-catalog-overlay.md @@ -104,8 +104,8 @@ The minimum `catalog list --json` contract should be small: - identity: stable id, command path/name, and display title or description - provenance: source kind, source id, and discovery mode -- scope: visibility/lens membership so consumers know where the entry is meant - to appear +- exposure: whether the source is suitable for public catalog/docs output or + should stay internal unless explicitly requested - safety summary: risk, effect mode, and confirmation requirement when known Fields such as examples, aliases, command hints, effects, owner, status, @@ -137,7 +137,7 @@ type CommandEffectProfile = { }; type CatalogExposure = { - visibility?: readonly ("docs" | "prompt" | "audit" | "operator" | "policy")[]; + tier?: "public" | "internal"; }; ``` @@ -150,7 +150,7 @@ type CatalogExposure = { - Plugin CLI descriptors already own plugin id, parent path, descriptor name, description, and subcommand shape through the plugin registry. They should only need plugin-native `catalogExposure`, `effectProfile`, and a - hidden/private marker if generated catalog views must omit a placeholder. + `hidden` marker if generated catalog views must omit a placeholder. - Node/operator commands should come from the node pairing/runtime declaration, not from a global catalog metadata bag. @@ -162,11 +162,18 @@ missing facts: - `catalogExposure?` - plugin descriptor `hidden?` +`catalogExposure` is not a per-consumer allowlist. It should not say "docs but +not audit" or "operator but not policy". Those choices belong in catalog lenses. +The source registry should only say whether the entry is suitable for public +catalog/docs output or should stay internal by default. Explicit `hidden` +markers remain useful for plugin placeholders or private/local QA surfaces that +should be omitted from generated catalog views unless a developer asks for them. + The catalog output can still present a normalized record with ids, source -labels, ownership, dispatch mode, status, examples, and derived summaries, but -those should be derived or supplied by explicit catalog overlays rather than -forced into every source registry. This keeps the registries familiar and puts -the integration burden in the catalog layer, where it belongs. +labels, ownership, dispatch mode, status, examples, lens membership, and derived +summaries, but those should be derived or supplied by explicit catalog overlays +rather than forced into every source registry. This keeps the registries +familiar and puts the integration burden in the catalog layer, where it belongs. ## Motivation From 00954d739440e5be7a0843ed335bd633acc77669 Mon Sep 17 00:00:00 2001 From: Gio Della-Libera Date: Thu, 9 Jul 2026 14:45:04 -0700 Subject: [PATCH 18/26] Define catalog effect profile semantics --- rfcs/0016-cli-catalog-overlay.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/rfcs/0016-cli-catalog-overlay.md b/rfcs/0016-cli-catalog-overlay.md index 4900a9b1..4086b5f7 100644 --- a/rfcs/0016-cli-catalog-overlay.md +++ b/rfcs/0016-cli-catalog-overlay.md @@ -175,6 +175,32 @@ summaries, but those should be derived or supplied by explicit catalog overlays rather than forced into every source registry. This keeps the registries familiar and puts the integration burden in the catalog layer, where it belongs. +## Effect Profile Semantics + +`CommandEffectProfile` describes the operational shape of a command or tool. It +does not grant permission, bypass confirmation, or replace the command's own +validation. + +- `effectMode: "read"` means the surface is expected to inspect or report state + without intentionally changing OpenClaw, the host, a remote service, or user + data. Examples include status, list, health, and help-style commands. +- `effectMode: "mutating"` means the surface is expected to change state, + configuration, files, sessions, plugin state, node state, or external service + state. +- `effectMode: "mixed"` means the surface has both read and mutating + subcommands, or the top-level descriptor is too broad to classify as only one + mode. The catalog can refine this at a deeper command path when the registry + has enough detail. +- `confirmationRequired` means callers should expect an explicit human/operator + confirmation boundary before the effect is committed. It is a catalog signal, + not the enforcement mechanism. +- `risk` is separate from `effectMode`. A read command can still be medium or + high risk if it exposes sensitive data, and a mutating command can be low risk + if it only changes local ephemeral state. +- `commandHints` are concise invocation examples used by generated docs, + operator summaries, or compact prompt projections. They are not a parser or a + promise that the command accepts only those forms. + ## Motivation OpenClaw already has several bounded operational surfaces: session status, From 35900e653f74da557ec28553de4924f8c34cef33 Mon Sep 17 00:00:00 2001 From: Gio Della-Libera Date: Thu, 9 Jul 2026 16:10:14 -0700 Subject: [PATCH 19/26] Clarify final catalog source registry framing --- rfcs/0016-cli-catalog-overlay.md | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/rfcs/0016-cli-catalog-overlay.md b/rfcs/0016-cli-catalog-overlay.md index 4086b5f7..0a173fd5 100644 --- a/rfcs/0016-cli-catalog-overlay.md +++ b/rfcs/0016-cli-catalog-overlay.md @@ -117,16 +117,11 @@ prompt, generated-docs, and node/operator detail as follow-up lenses. ## Registry Metadata Budget -The higher-risk part is not the JSON output shape; it is what gets added to -existing registries as source metadata. The prototype used a generic -`catalog?: CliCatalogMetadata` bag on CLI descriptors, routed command entries, -and plugin CLI descriptors. That was useful for discovery, but it is not the -right default shape for a stable OpenClaw contract. - -The better direction is to keep each existing registry native and small, then -make the catalog builder do the hard N-to-1 normalization work. The source -registry additions should be typed around the facts they actually represent: -operational effects and catalog exposure. +The source-registry addition is intentionally small and compliance-oriented: a +command/tool can report its operational effect consistently wherever it appears. +Source registries should stay native and small, while the catalog builder does +the hard N-to-1 normalization work. The two source concepts are operational +effects and catalog exposure. ```ts type CommandEffectProfile = { @@ -154,9 +149,8 @@ type CatalogExposure = { - Node/operator commands should come from the node pairing/runtime declaration, not from a global catalog metadata bag. -For a first stable registry contract, avoid adding a 17-field generic bag to -multiple registries. Prefer small native optional structs that map to concrete -missing facts: +For a first stable registry contract, prefer small native optional structs that +map to concrete missing facts: - `effectProfile?` - `catalogExposure?` From 18ee8ac89697a04068bee95e67f7b761ec2d2f7f Mon Sep 17 00:00:00 2001 From: Gio Della-Libera Date: Thu, 9 Jul 2026 16:45:09 -0700 Subject: [PATCH 20/26] Clarify catalog RFC inventory boundary --- rfcs/0016-cli-catalog-overlay.md | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/rfcs/0016-cli-catalog-overlay.md b/rfcs/0016-cli-catalog-overlay.md index 0a173fd5..57d3a7a1 100644 --- a/rfcs/0016-cli-catalog-overlay.md +++ b/rfcs/0016-cli-catalog-overlay.md @@ -112,8 +112,8 @@ Fields such as examples, aliases, command hints, effects, owner, status, confidence, policy keys, approval kind, trust boundary, and node-specific availability are valuable, but they should remain advisory or lens-specific until a concrete consumer needs them. If maintainers want a narrower first PR, -the catalog should trim to the minimum contract above and leave audit/policy, -prompt, generated-docs, and node/operator detail as follow-up lenses. +the catalog should trim to the minimum contract above and leave audit inventory, +prompt projection, generated-docs, and node/operator detail as follow-up lenses. ## Registry Metadata Budget @@ -232,13 +232,13 @@ easier to inspect, document, test, audit, and route. - Keep prompt-facing metadata lean enough to avoid turning the catalog into a large prompt tax. - Provide a programmatic and CLI-readable list of OpenClaw command/tool surfaces - for maintainers, operators, docs, tests, audit, and future policy/admin + for maintainers, operators, docs, tests, audit inventory, and future admin consumers. - Distinguish static descriptors, route-policy entries, ownerless adapter entries, runtime-registered commands, and plugin descriptor entries with source/discovery metadata. -- Generate scoped lenses from the same inventory for prompts, audit/policy - review, smoke coverage, and operator handoffs. +- Generate scoped lenses from the same inventory for prompts, audit inventory, + smoke coverage, and operator handoffs. - Add drift guards so descriptor-backed entries, list output, prompt projection, and consumer lenses stay aligned. @@ -296,7 +296,7 @@ The initial owner mapping is: - Command-route entries own routed-operation metadata such as route title, prompt risk, confirmation requirement, and command hints. - Plugin CLI descriptors own plugin command metadata, including optional - visibility, risk, confirmation, effect mode, and command hints. + catalog exposure, risk, confirmation, effect mode, and command hints. - The adapter owns only ownerless tool-backed surfaces such as `skill_workshop`, `session_status`, `sessions_spawn`, and `process` until OpenClaw has a structured source for them. @@ -317,7 +317,7 @@ Each surface entry declares: - `source_kind` - `source_id` - `discovery_mode` -- `visibility` +- `catalog_exposure` - `intent` - `examples` - `aliases` @@ -365,9 +365,10 @@ The initial implementation has a normalized inventory layer plus scoped lenses: entries, labeled by plugin ID and discovery mode, without making plugin execution a new default catalog requirement. - Catalog metadata adapters on existing owners: CLI descriptors, route entries, - and plugin CLI descriptors can carry focused metadata such as examples, - aliases, risk, confirmation, effect mode, effects, visibility, and command - hints. + and plugin CLI descriptors can carry focused source metadata through + `effectProfile` and `catalogExposure`. The catalog layer can then derive + examples, aliases, effects, ownership, status, dispatch mode, and lens + membership without forcing those fields into every registry. - Ownerless tool adapter: supplies the same metadata only for non-CLI or tool-backed model surfaces that do not yet have an owning descriptor or route. - Prompt lens: exposes only lean model-facing routing fields and filters by @@ -460,7 +461,7 @@ openclaw catalog list --markdown ``` The command is not an execution dispatcher. JSON output is the joined structured -view for humans, automation, docs, and future policy/admin consumers. +view for humans, automation, docs, audit inventory, and future admin consumers. Markdown output is a concise operator view. ### Proposed Implementation Stack @@ -597,8 +598,8 @@ ten tiny PRs. - Deliverables: runtime Commander-tree entries, opt-in plugin descriptor entries, `catalog audit`, `catalog test-matrix`, and `catalog summary`. - Scenario: maintainers can inspect static, runtime, plugin, route, and tool - surfaces by the lens that matches their job: live inventory, audit/policy - review, smoke coverage planning, or operator handoff. + surfaces by the lens that matches their job: live inventory, audit + inventory, smoke coverage planning, or operator handoff. - Non-goal: do not force-load command trees or plugin runtime code only for discovery; do not fail CI or enforce policy from the first reports. - Acceptance: dynamic entries are source-labeled, plugin entries are opt-in From 12efdb8e3d2bb5b2508061b98de784c840c7925e Mon Sep 17 00:00:00 2001 From: Gio Della-Libera Date: Fri, 10 Jul 2026 12:04:39 -0700 Subject: [PATCH 21/26] Narrow CLI catalog RFC to initial scope --- rfcs/0016-cli-catalog-overlay.md | 804 ------------------------------- rfcs/0016-command-catalog.md | 386 +++++++++++++++ 2 files changed, 386 insertions(+), 804 deletions(-) delete mode 100644 rfcs/0016-cli-catalog-overlay.md create mode 100644 rfcs/0016-command-catalog.md diff --git a/rfcs/0016-cli-catalog-overlay.md b/rfcs/0016-cli-catalog-overlay.md deleted file mode 100644 index 57d3a7a1..00000000 --- a/rfcs/0016-cli-catalog-overlay.md +++ /dev/null @@ -1,804 +0,0 @@ ---- -title: CLI Catalog View for OpenClaw Command Surfaces -authors: - - Gio -created: 2026-07-04 -last_updated: 2026-07-09 -status: draft -issue: -rfc_pr: https://github.com/openclaw/rfcs/pull/32 ---- - -# Proposal: CLI Catalog View for OpenClaw Command Surfaces - -## Summary - -Add a read-only `openclaw catalog` command over existing OpenClaw command and -tool metadata so maintainers, operators, docs, tests, and prompt routing can -inspect the same normalized inventory. OpenClaw already has internal command -catalogs, descriptors, route metadata, plugin descriptors, and tool surfaces, -but it does not have a user-facing command that joins them into one structured -view. This proposal adds that missing view without replacing the existing -registries. - -The catalog view is metadata only. It does not add a new execution dispatcher, -runtime hook, gateway plugin, policy engine, or expression language. Existing -commands and tools continue to own validation, permissions, confirmation, -execution, and results. - -## Implementation Review Links - -There is already one upstream OpenClaw draft PR with the full end-state branch: - -- Rollup implementation PR: [openclaw/openclaw#100960](https://github.com/openclaw/openclaw/pull/100960) - -For review convenience, the same work is also prepared as fork-local stacked -draft PRs. These are not asking maintainers to merge from the fork; they are a -review aid so the stack can be read one layer at a time. If maintainers prefer, -I am happy to open the same PRs against `openclaw/openclaw` separately and merge -them in order. - -- PR1 foundation: [giodl73-repo/openclaw#11](https://github.com/giodl73-repo/openclaw/pull/11) -- PR2 dynamic/operator lenses: [giodl73-repo/openclaw#12](https://github.com/giodl73-repo/openclaw/pull/12) -- PR3 prompt projection: [giodl73-repo/openclaw#13](https://github.com/giodl73-repo/openclaw/pull/13) -- PR4 schema fixtures: [giodl73-repo/openclaw#14](https://github.com/giodl73-repo/openclaw/pull/14) -- PR5 generated docs: [giodl73-repo/openclaw#15](https://github.com/giodl73-repo/openclaw/pull/15) -- PR6 hardening and consumer contract: [giodl73-repo/openclaw#16](https://github.com/giodl73-repo/openclaw/pull/16) - -## Draft Status And Proof - -This RFC is still a draft and should not be merged as accepted until -maintainers choose the public CLI/API boundary and the RFC lifecycle is -complete. This PR can serve as the design discussion vehicle; if maintainers -prefer a separate `maintainer-discussion` thread, that link should be added here -before acceptance. - -The linked implementation branch is also draft review material, not proof that -the RFC is already accepted. Current implementation validation is tracked on -[openclaw/openclaw#100960](https://github.com/openclaw/openclaw/pull/100960) -and includes catalog unit coverage, generated fixture checks, generated docs -checks, formatting checks, and one Codex review pass per stacked branch. Runtime -behavior proof should stay with the implementation PR because this RFC -repository only carries the design document. - -The current implementation review branch inventories: - -- 61 CLI descriptors -- 97 command routes -- 14 routed operations -- 5 explicit agent/tool surfaces -- supplied node/operator command metadata - -The audit/report layer then groups the same inventory by state-changing versus -read-only/mixed effects, confirmation-required surfaces, route policy keys, -routes missing policy keys, routed-operation smoke-test coverage gaps, -node/operator commands, and approval-required node commands. - -This is not just a static help dump. `openclaw catalog list` collects the live -Commander tree for the current invocation, and -`openclaw catalog list --plugin-descriptors` also includes plugin-provided CLI -descriptor metadata when that metadata is explicitly requested. Scout's -plugin-only container proof demonstrates why that distinction matters: the -loaded config currently exposes 13 plugins, 11 enabled plugins, 2 plugin CLI -commands, 8 plugin tools, and 23 allowed command/tool names. - -## Field Budget And Trim Boundary - -The field surface should be treated as part of the proposal, not incidental -implementation detail. The implementation branch currently explores several -entry kinds with different field counts: - -- descriptors: about 9 fields per entry -- command routes: about 8 fields per entry -- routed operations: about 5 fields per entry -- runtime commands: about 13 fields per entry -- plugin commands: about 17 fields per entry -- supplied node/operator commands: about 20 fields per entry -- prompt projection entries: about 9 fields per entry - -That is useful for review because it shows the catalog can serve audit, docs, -prompt, operator, and test-matrix consumers, but it should not all become the -minimum stable contract by accident. - -The minimum `catalog list --json` contract should be small: - -- identity: stable id, command path/name, and display title or description -- provenance: source kind, source id, and discovery mode -- exposure: whether the source is suitable for public catalog/docs output or - should stay internal unless explicitly requested -- safety summary: risk, effect mode, and confirmation requirement when known - -Fields such as examples, aliases, command hints, effects, owner, status, -confidence, policy keys, approval kind, trust boundary, and node-specific -availability are valuable, but they should remain advisory or lens-specific -until a concrete consumer needs them. If maintainers want a narrower first PR, -the catalog should trim to the minimum contract above and leave audit inventory, -prompt projection, generated-docs, and node/operator detail as follow-up lenses. - -## Registry Metadata Budget - -The source-registry addition is intentionally small and compliance-oriented: a -command/tool can report its operational effect consistently wherever it appears. -Source registries should stay native and small, while the catalog builder does -the hard N-to-1 normalization work. The two source concepts are operational -effects and catalog exposure. - -```ts -type CommandEffectProfile = { - effectMode: "read" | "mutating" | "mixed"; - confirmationRequired?: boolean; - risk?: "low" | "medium" | "high"; - commandHints?: readonly string[]; -}; - -type CatalogExposure = { - tier?: "public" | "internal"; -}; -``` - -- CLI descriptors already own `name`, `description`, `hasSubcommands`, and - `parentDefaultHelp`. They should only need missing `catalogExposure` or - `effectProfile` data when those facts cannot be inferred. -- Routed command entries already own `commandPath`, `exact`, route id, and - policy data. They should only need route-local `effectProfile` data when - policy/route data cannot express it. -- Plugin CLI descriptors already own plugin id, parent path, descriptor name, - description, and subcommand shape through the plugin registry. They should - only need plugin-native `catalogExposure`, `effectProfile`, and a - `hidden` marker if generated catalog views must omit a placeholder. -- Node/operator commands should come from the node pairing/runtime declaration, - not from a global catalog metadata bag. - -For a first stable registry contract, prefer small native optional structs that -map to concrete missing facts: - -- `effectProfile?` -- `catalogExposure?` -- plugin descriptor `hidden?` - -`catalogExposure` is not a per-consumer allowlist. It should not say "docs but -not audit" or "operator but not policy". Those choices belong in catalog lenses. -The source registry should only say whether the entry is suitable for public -catalog/docs output or should stay internal by default. Explicit `hidden` -markers remain useful for plugin placeholders or private/local QA surfaces that -should be omitted from generated catalog views unless a developer asks for them. - -The catalog output can still present a normalized record with ids, source -labels, ownership, dispatch mode, status, examples, lens membership, and derived -summaries, but those should be derived or supplied by explicit catalog overlays -rather than forced into every source registry. This keeps the registries -familiar and puts the integration burden in the catalog layer, where it belongs. - -## Effect Profile Semantics - -`CommandEffectProfile` describes the operational shape of a command or tool. It -does not grant permission, bypass confirmation, or replace the command's own -validation. - -- `effectMode: "read"` means the surface is expected to inspect or report state - without intentionally changing OpenClaw, the host, a remote service, or user - data. Examples include status, list, health, and help-style commands. -- `effectMode: "mutating"` means the surface is expected to change state, - configuration, files, sessions, plugin state, node state, or external service - state. -- `effectMode: "mixed"` means the surface has both read and mutating - subcommands, or the top-level descriptor is too broad to classify as only one - mode. The catalog can refine this at a deeper command path when the registry - has enough detail. -- `confirmationRequired` means callers should expect an explicit human/operator - confirmation boundary before the effect is committed. It is a catalog signal, - not the enforcement mechanism. -- `risk` is separate from `effectMode`. A read command can still be medium or - high risk if it exposes sensitive data, and a mutating command can be low risk - if it only changes local ephemeral state. -- `commandHints` are concise invocation examples used by generated docs, - operator summaries, or compact prompt projections. They are not a parser or a - promise that the command accepts only those forms. - -## Motivation - -OpenClaw already has several bounded operational surfaces: session status, -process control, gateway operations, skill proposal lifecycle, delegation, -config updates, exports, diagnostics, and similar command or tool surfaces. -Their metadata is split across useful internal sources such as CLI descriptors, -`cliCommandCatalog`, routed-command definitions, plugin descriptors, and prompt -guidance. Today there is no `openclaw catalog` command that answers "what -command/tool surfaces exist, where did they come from, and which ones are safe -for this context?" - -That creates three problems: - -- no single place lists the available command/tool surfaces with source labels - and risk metadata -- docs, tests, prompts, and audits can drift because they each infer the same - inventory differently -- model-facing guidance can phrase or sequence bounded operations incorrectly - when it relies on prose instead of structured metadata -- repeated flows consume prompt space restating bounded behavior already present - in command metadata - -The goal is not primarily token reduction. The bigger win is a single -inspection point for existing command/tool metadata so bounded actions become -easier to inspect, document, test, audit, and route. - -## Goals - -- Provide one read-only catalog view over existing OpenClaw command and tool - registries. -- Let prompt routing choose an existing command or tool surface from reviewable - metadata. -- Keep the selected surface responsible for validation, permissions, - confirmation, execution, and output. -- Keep prompt-facing metadata lean enough to avoid turning the catalog into a - large prompt tax. -- Provide a programmatic and CLI-readable list of OpenClaw command/tool surfaces - for maintainers, operators, docs, tests, audit inventory, and future admin - consumers. -- Distinguish static descriptors, route-policy entries, ownerless adapter - entries, runtime-registered commands, and plugin descriptor entries with - source/discovery metadata. -- Generate scoped lenses from the same inventory for prompts, audit inventory, - smoke coverage, and operator handoffs. -- Add drift guards so descriptor-backed entries, list output, prompt projection, - and consumer lenses stay aligned. - -## Non-Goals - -- Replacing open-ended reasoning, code review, design review, or - troubleshooting. -- Turning every prompt into a DSL. -- Replacing existing CLI, route, plugin, provider, channel, or model catalogs. -- Adding a general-purpose expression language. -- Encoding product judgment or policy enforcement into the catalog itself. -- Adding a new execution surface, dispatcher, runtime hook, or gateway plugin. -- Requiring skill authors or command owners to learn a new authoring format in - the first pass. -- Exposing this as a public plugin SDK contract in the first implementation. -- Treating prompt projection as required for the catalog list, audit, docs, or - operator views to be useful. - -## Proposal - -Start with a hierarchical, additive `openclaw catalog` view over existing -registries instead of a second command registry. The first list is structured -as: - -- `cli.descriptors`: the existing top-level/core and sub-CLI descriptor - inventory. -- `cli.commandRoutes`: the existing command-path routing and startup-policy - registry. -- `cli.routedOperations`: the mechanical fast-path route IDs derived from the - command-route registry and routed-command definitions. -- Catalog metadata fields on owning descriptors and routes: optional fields on - CLI descriptors, command-route entries, and plugin CLI descriptors provide - prompt, audit, operator, and docs metadata where those registries already own - the surface. -- `agentToolSurfaces`: projected tool-backed or non-CLI surfaces. Most entries - should come from the owning descriptor/route/plugin metadata; explicit - adapter entries are reserved for surfaces that do not yet have an owning - structured registry. -- `cli.runtimeCommands`: optional entries discovered from the currently - registered Commander tree for this invocation. -- `cli.pluginCommands`: optional plugin CLI descriptor entries, source-labeled - by plugin ID and only included when explicitly requested or already available - to the caller. -- `promptProjection`: a compact model-facing subset derived from routed - operations, prompt-visible agent/tool surfaces, and explicitly prompt-enabled - plugin entries. - -Exact counts are intentionally omitted from the contract. They are useful in -fixtures and reports as reviewable snapshots, but command inventory changes -over time and should not become a permanent compatibility promise. - -The initial owner mapping is: - -- CLI descriptors own command-level catalog metadata such as `gateway`. -- Command-route entries own routed-operation metadata such as route title, - prompt risk, confirmation requirement, and command hints. -- Plugin CLI descriptors own plugin command metadata, including optional - catalog exposure, risk, confirmation, effect mode, and command hints. -- The adapter owns only ownerless tool-backed surfaces such as - `skill_workshop`, `session_status`, `sessions_spawn`, and `process` until - OpenClaw has a structured source for them. - -Explicit adapter entries are the exception path, not a new parallel registry. -They cover tool-backed or non-CLI surfaces that do not already have enough -structured metadata to join from existing registries. If OpenClaw later adds -structured descriptors for those surfaces, the catalog should read them from -that source instead of keeping duplicate hand-authored metadata. - -Each surface entry declares: - -- `id` -- `title` -- `kind` -- `target` -- `source` -- `source_kind` -- `source_id` -- `discovery_mode` -- `catalog_exposure` -- `intent` -- `examples` -- `aliases` -- `owner` -- `status` -- `confidence` -- `risk` -- `confirmation` -- `effect_mode` -- `effects` -- `dispatch_mode` -- `command_hints` - -Example shape: - -```yaml -id: gateway -title: Gateway control -kind: command -dispatch_mode: hybrid -target: gateway -intent: Inspect, reconfigure, or restart the OpenClaw Gateway. -risk: medium -confirmation: true -effect_mode: mixed -command_hints: - - gateway status - - gateway restart - - gateway config.schema.lookup - - gateway config.apply -``` - -### Architecture - -The initial implementation has a normalized inventory layer plus scoped lenses: - -- CLI descriptor inventory: reads existing core and sub-CLI descriptors. -- Command-route inventory: reads the existing `cliCommandCatalog` routing and - startup-policy entries. -- Routed-operation inventory: derives route IDs and command paths from current - routed-command metadata. -- Runtime command inventory: can enumerate the currently registered Commander - tree for the active invocation, including nested commands already present. -- Plugin descriptor inventory: can project plugin CLI descriptors into catalog - entries, labeled by plugin ID and discovery mode, without making plugin - execution a new default catalog requirement. -- Catalog metadata adapters on existing owners: CLI descriptors, route entries, - and plugin CLI descriptors can carry focused source metadata through - `effectProfile` and `catalogExposure`. The catalog layer can then derive - examples, aliases, effects, ownership, status, dispatch mode, and lens - membership without forcing those fields into every registry. -- Ownerless tool adapter: supplies the same metadata only for non-CLI or - tool-backed model surfaces that do not yet have an owning descriptor or route. -- Prompt lens: exposes only lean model-facing routing fields and filters by - available tools plus explicitly prompt-enabled plugin IDs. -- Audit, coverage, and operator lenses: consume the same inventory to group risk, - effect mode, route policy, coverage gaps, and handoff summaries. - -Consumers such as the prompt renderer, catalog list command/script, generated -reference docs, drift guards, audit reports, coverage reports, and operator -summaries read from those APIs instead of duplicating metadata. - -The first stack should demonstrate live value in more than one consumer: -`openclaw catalog list --json` for inspection, generated docs for reference -freshness, audit/test-matrix/summary outputs for maintainer review, and prompt -projection for model-facing routing. Plugin metadata remains opt-in and -metadata-only so plugin authors can make command surfaces discoverable without -the catalog executing arbitrary plugin runtime code. - -### Maintainability Model - -The catalog is designed to be easy to maintain because it is a view over -existing OpenClaw data structures, not a replacement for them. - -- CLI descriptors continue to come from the existing core and sub-CLI - descriptor registries, with optional catalog metadata on the descriptor that - owns the command. -- Command paths and startup-policy metadata continue to come from the existing - command catalog, with route-local catalog metadata for routed operations that - need prompt/audit/operator labels. -- Plugin command metadata lives on plugin CLI descriptors so plugin authors do - not need a second catalog registration path. -- Routed operations are derived from existing command-route metadata instead of - loading route runners or defining a second operation registry. -- Tool-backed and non-CLI surfaces use explicit adapter metadata only where - OpenClaw does not already have a structured descriptor, route, or plugin - entry to read. -- Prompt guidance, generated docs, audit reports, and future operator views all - consume catalog APIs instead of maintaining their own hardcoded lists. - -The expected maintenance path is therefore narrow: when an existing command, -route, or tool surface changes, the catalog either picks that up from the -existing registry or a focused guard points to the missing metadata update. The -catalog should not grow into a new execution system, policy engine, or parallel -source of truth. - -### Relationship to Existing Registries - -This is additive. OpenClaw already has internal command catalogs and descriptor -registries, but current `main` does not expose a user-facing -`openclaw catalog` command or one joined read-only inventory. - -The closest existing source is `cliCommandCatalog`, which owns command paths, -startup policy, and route policy keys. Other sources own adjacent pieces: -sub-CLI descriptors own help and registration metadata, routed-command -definitions own mechanical fast paths, plugin descriptors own plugin CLI -metadata, and prompts/docs describe selected usage in prose. - -This RFC keeps those sources as the owners. The catalog command reads them, -adds small optional metadata where the owning source needs prompt/audit/operator -labels, and exposes joined JSON/Markdown views for docs, audit, test planning, -prompt routing, and operator review. It should not become a parallel registry or -new execution path. - -### Runtime Flow - -1. The catalog list API builds the full hierarchy from existing registries and - optional catalog metadata on owning descriptors/routes/plugins, plus - ownerless tool adapters where no owning registry exists yet. -2. The prompt renderer reads the prompt projection API, not the full catalog - list. -3. Prompt routing identifies a routed operation or agent/tool surface by `id` or - lean metadata match. -4. The model chooses the existing command or tool surface described by that - entry. -5. The selected surface validates arguments, policy, and preconditions using - existing behavior. -6. If required, the selected surface asks for confirmation. -7. The selected command or tool performs the operation. -8. OpenClaw returns the normal command/tool result and any structured state that - surface already exposes. - -### CLI Access - -Expose the read-only operator view through: - -```bash -openclaw catalog list -openclaw catalog list --json -openclaw catalog list --markdown -``` - -The command is not an execution dispatcher. JSON output is the joined structured -view for humans, automation, docs, audit inventory, and future admin consumers. -Markdown output is a concise operator view. - -### Proposed Implementation Stack - -The implementation should land as a small review stack that shows the catalog -view first, then layers dynamic inventory, prompt routing, drift guards, docs, -and hardening on top. - -1. Foundation catalog view: add `buildCatalogList()`, `openclaw catalog list`, - static CLI descriptors with optional catalog metadata, command routes with - route-local catalog metadata, routed operations, ownerless tool adapters, - source labels, and parseable JSON/Markdown output. -2. Dynamic and operator lenses: add runtime Commander-tree entries, opt-in - plugin descriptor entries, `catalog audit`, `catalog test-matrix`, and - `catalog summary`. -3. Prompt projection: add the lean prompt-facing projection and prompt renderer - that read from the catalog rather than duplicating command prose. - This PR is intentionally separate so maintainers can review model-facing - behavior apart from the catalog list, audit, docs, and operator surfaces. -4. Schema fixtures: add checked JSON fixtures that protect schema versions, - required fields, stable IDs, and value kinds while treating counts as - reviewable snapshots. -5. Generated docs: generate the catalog reference page from the same APIs, with - docs-map/i18n updates and a `--check` freshness mode. - This is a drift guard for a new public CLI reference, not a hand-written - docs exercise. -6. Hardening: enrich runtime/plugin detail, preserve hidden/private plugin - metadata through registry normalization, write richer advisory report - artifacts, and document the CLI-first consumer contract. - -### Full Integration Plan - -The catalog should become the shared metadata source for mechanical OpenClaw -surfaces, not just prompt text. Integration should proceed in narrow consumers -that prove value while keeping execution with the existing command and tool -implementations. - -1. Prompt routing: keep the system prompt on the lean projection only. It should - classify bounded requests into existing routed operations or agent/tool - surfaces, then use the current command or tool path. -2. Reference docs: generate user-facing and maintainer-facing catalog docs from - `buildCatalogList()` so command inventory, route inventory, routed - operations, and agent/tool surfaces do not drift from hand-written docs. -3. Audit and policy inventory: add read-only reports that answer questions such - as "which surfaces mutate state", "which surfaces require confirmation", - "which command paths bypass config guard", and "which routes can use network - proxy bypass". These reports should consume catalog metadata and existing - policy data; they should not enforce policy themselves. -4. Test matrix generation: derive smoke-test candidates from `cli.routedOperations` - and command paths. The generated matrix should identify missing coverage for - mechanical routes without replacing the route implementations. -5. Operator and admin views: expose the same structured data to diagnostics, - debug views, and future admin surfaces so operators can inspect what OpenClaw - can do mechanically without scraping help output. -6. Drift guards: keep compatibility checks around descriptor presence, - route-definition alignment, generated docs, prompt projection size, and - catalog JSON shape. Counts can be checked as inventory snapshots, while - schema and ID stability should be checked more strictly. -7. Future automation adapters: if later work needs automation beyond prompt - routing, build adapters that select a catalog entry and call the existing - command or tool implementation. Do not introduce a new catalog dispatcher - until a concrete consumer proves that the existing command/tool invocation - path is insufficient. - -### Node-Operator Catalog Support - -Node/operator command metadata should be folded through the first six PRs rather -than introduced as a separate follow-up. The base catalog already lists `node` and -`nodes` as CLI descriptors, command-route entries, and runtime Commander -entries, but paired-node operation needs structured command metadata and a -scoped prompt view rather than a dump of every node command into every model -prompt. - -This support should answer a narrower question: when an OpenClaw agent is -operating through a paired node, which node commands are available, what -arguments do they expect, what approval boundary applies, and which commands -should the model see for the current node context? - -Evidence comes from the current `gim-home/m` node-mode command stack: - -- `gim-home/m#4045` adds node-routed MCP commands: - `mcp.help`, `mcp.invoke`, `mcp.status`, and `mcp.cancel`. -- `gim-home/m#4086` adds filesystem node commands: - `filesystem.read`, `filesystem.write`, and `filesystem.patch`. -- `gim-home/m#4088` adds browser/file-open node commands: - `browser.open` and `file.openWithDefaultApp`, plus Desktop-owned Playwright - MCP approval behavior. - -Those PRs show the catalog value beyond generic prompt routing. Each node slice -has a command name, argument shape, approval model, risk boundary, docs text, -and model-facing behavior that must stay aligned. Without a structured catalog -lens, every new node command family requires manual prompt/docs/help updates and -can drift from the actual Gateway/Desktop approval path. - -The node/operator catalog support should be scoped: - -- General catalog/audit views list all known `node`/`nodes` descriptors, - command routes, runtime commands, and plugin-provided node command - descriptors. -- Prompt projection includes only node commands available in the active - node-control context. -- Low-risk read/status/help commands can be prompt-visible by default in node - mode. -- Mutating or side-effecting commands such as filesystem writes, browser opens, - app/file opens, shell/system commands, or M365 actions carry risk, - confirmation, and approval-boundary metadata. -- Plugin-provided `nodes ...` commands remain opt-in and trust-scoped. - -This is still metadata-only. The selected node command continues to execute -through the existing OpenClaw/Gateway/Desktop command path, and Desktop remains -the owner of local validation, permission cards, policy, approval memory, and -runtime execution. - -### Proposed PR Plan - -Because the catalog's value is the combination of normalized inventory plus -consumer-specific lenses, the first implementation stack should show the shared -catalog view and its most important consumers without making reviewers evaluate -ten tiny PRs. - -1. Foundation catalog view - - Deliverables: `buildCatalogList()`, `openclaw catalog list`, static core - and sub-CLI descriptors with optional catalog metadata, command-route - policy entries with route-local catalog metadata, routed operations, - ownerless adapter surfaces, schema version, source/discovery metadata, and - JSON/Markdown output. - - Scenario: `openclaw catalog list --json` shows OpenClaw command and tool - surfaces in one source-labeled shape. - - Non-goal: no dispatcher, policy enforcement, or replacement registry. - - Acceptance: output is parseable, source-labeled, and derived from existing - registries wherever possible. - -2. Dynamic inventory and operator lenses - - Deliverables: runtime Commander-tree entries, opt-in plugin descriptor - entries, `catalog audit`, `catalog test-matrix`, and `catalog summary`. - - Scenario: maintainers can inspect static, runtime, plugin, route, and tool - surfaces by the lens that matches their job: live inventory, audit - inventory, smoke coverage planning, or operator handoff. - - Non-goal: do not force-load command trees or plugin runtime code only for - discovery; do not fail CI or enforce policy from the first reports. - - Acceptance: dynamic entries are source-labeled, plugin entries are opt-in - or caller-supplied, and operator/audit outputs consume catalog data rather - than prompt text or hand-maintained lists. - -3. Prompt projection - - Deliverables: lean prompt projection, prompt renderer, available-tool - filtering, prompt budget guard, and explicit opt-in for plugin descriptor - commands that are allowed into prompt scope. - - Scenario: the model sees the small set of surfaces available in its - current scope without seeing the full audit or operator inventory. - - Non-goal: do not dump the full catalog into the prompt. - - Acceptance: prompt projection remains small, filters unavailable tools, and - only includes plugin entries when an allowed plugin ID is supplied. - -4. Schema fixtures - - Deliverables: checked fixtures for `catalog list`, `catalog audit`, - `catalog test-matrix`, `catalog summary`, and prompt projection output. - - Scenario: maintainers can review catalog contract changes intentionally - instead of discovering JSON-shape drift through downstream consumers. - - Non-goal: do not freeze every command count as a compatibility promise. - - Acceptance: fixture checks fail on removed/renamed fields, unstable IDs, or - schema-version drift, but allow deliberate inventory count updates. - -5. Generated reference docs - - Deliverables: generated docs for the catalog commands and lenses, plus - docs-map and i18n glossary updates where the generated page participates in - the normal docs index. - - Scenario: users and maintainers can inspect the catalog surfaces from docs - generated by the same APIs used by automation. - - Non-goal: do not hand-write parallel catalog tables. - - Acceptance: docs generation has a `--check` mode, consumes catalog APIs, - preserves checked-in formatting, and keeps public docs deterministic when - private/local QA CLI flags are enabled. - -6. Hardening and consumer boundary - - Deliverables: richer runtime/plugin metadata, hidden/private plugin - metadata preservation through registry normalization, richer advisory - report artifacts, and a documented CLI-first consumer contract. - - Scenario: downstream consumers can use `openclaw catalog ... --json` and - advisory report artifacts without scraping help output or coupling to - prompt-rendering internals. - - Non-goal: do not promise `src/` implementation imports as a published API - and do not make advisory report artifacts blocking gates. - - Acceptance: runtime/plugin entries stay source-labeled, hidden/private - commands stay out of public lenses, advisory outputs remain clearly - non-blocking, and any future package export is added deliberately. - -The node/operator work should be distributed across the six PRs: - -- PR1 foundation: define the supplied `cli.nodeCommands` list shape and its - source, availability, approval, risk, effect, argument-hint, and trust-boundary - fields. -- PR2 dynamic/operator lenses: include node command metadata in audit, - test-matrix, and operator summary views. -- PR3 prompt lens: add a scoped `node-operator` prompt projection that is - disabled by default. -- PR4 schema fixtures: snapshot representative paired-node/node-host command - records. -- PR5 generated docs: document node/operator commands as a supported dynamic - catalog family. -- PR6 hardening: carry node command fields through advisory reports and the - CLI-first consumer contract. - -### Node-Operator Shape - -The node/operator support has three internal pieces: - -1. Node command source metadata - - Deliverables: catalog metadata for node-routed command families from the - Gateway/Desktop node command source, including command ID, title, argument - hints, owner, risk, effect mode, confirmation requirement, approval kind, - and trust boundary. - - Scenario: `openclaw catalog list --json` can identify node commands such - as `mcp.invoke`, `filesystem.write`, and `browser.open` as node-operated - surfaces rather than opaque prose. - - Non-goal: do not execute node commands from the catalog and do not import - Desktop runtime code into OpenClaw catalog generation. - - Acceptance: node command metadata is source-labeled, generated or - supplied by the owning node command registry where possible, and absent - commands do not appear in prompt scope. - -2. Node-operator prompt projection - - Deliverables: a scoped prompt lens, for example - `listCliCatalogPromptSurfaces({ scope: "node-operator", ... })`, that - includes only node commands available to the active node context. - - Scenario: an OpenClaw agent operating a paired node sees how to inspect MCP - status, invoke an allowed MCP tool, read or patch workspace files, and open - browser/file targets without seeing unrelated catalog inventory. - - Non-goal: do not dump full audit metadata or every node/plugin command - into the default system prompt. - - Acceptance: prompt output is small, context-filtered, and carries enough - command/argument/risk hints for correct tool choice. - -3. Node trust/audit/test-matrix lens - - Deliverables: catalog audit/test-matrix support for node command families, - including approval kind, side-effect classification, command availability, - and smoke-test candidates. - - Scenario: maintainers can compare the OpenClaw node prompt surface against - the actual Desktop/Gateway node command stack and find missing coverage or - mismatched risk/approval metadata. - - Non-goal: do not make this a blocking CI gate until maintainers choose - explicit policy semantics. - - Acceptance: reports can cite node command families and approval boundaries - in a stable JSON shape suitable for PR review artifacts. - -### Review Learnings Incorporated - -The implementation review pass tightened several boundaries in this RFC: - -- Checked JSON fixtures are reviewable snapshots. They should protect schema - versions, required fields, stable IDs, and value kinds, while treating counts - and inventory membership as expected-to-change catalog snapshots. -- Public generated docs must stay deterministic. They should use the public - catalog shape, participate in existing docs gates, and avoid leaking - private/local QA surfaces even when those surfaces are enabled in a developer - environment. -- Static docs and live inventory serve different jobs. Generated docs describe - the stable catalog concepts; `catalog list --json` can include runtime - Commander entries for the current invocation; plugin descriptor entries should - appear only when the caller opts into or supplies that metadata. -- Plugin metadata must be preserved before filtering. Hidden/private markers - need to survive the real registry path, not only direct unit-test fixtures. -- The external contract is CLI-first for now. Until package exports are added - deliberately, downstream consumers should rely on `openclaw catalog ... --json` - rather than importing catalog builder modules from `src/`. -- Catalog reports should start advisory. They can produce PR artifacts and - review summaries, but they should not become blocking CI gates until - maintainers choose explicit policy semantics. - -## Rationale - -This design uses OpenClaw's existing command registration and tool contracts as -the source of truth. That keeps the catalog view small and reviewable while -avoiding a second control plane. - -The main alternative is to create a typed operation or DSL layer. That would -make bounded operations explicit, but it would also create a new surface that -could drift from current CLI/tool behavior. Starting from the CLI descriptor -catalog is lower risk because every catalog entry must point at an existing -surface. - -The prompt projection and catalog list APIs are intentionally separate. The -catalog list is the broad structured metadata view. The prompt needs only a -compact routing view. Separating them avoids prompt scraping while keeping token -cost visible. - -## Evaluation Plan - -Compare current prompt-driven behavior with catalog-view behavior on a fixed set -of bounded tasks: - -- set or inspect session state -- approve or reject a bounded action -- add or remove an allowlist entry -- advance a wizard step -- export session or trajectory data -- install, enable, disable, or refresh a skill/plugin -- collect a diagnostic or audit bundle -- operate a paired node through MCP, filesystem, browser/file-open, or future - system/M365 node commands - -Track: - -- correctness -- retries -- clarification turns -- total tokens -- tool calls -- latency -- manual intervention -- policy violations -- audit completeness - -The catalog view is better only if it is at least as safe as the current path, -reduces retries or prompt ambiguity on repeated mechanical operations, preserves -user-visible behavior, and produces a readable audit trail for covered actions. - -Example comparisons: - -| Task | Current behavior to compare | Catalog-view behavior to validate | -| --- | --- | --- | -| Inspect Gateway status | Prompt guidance or help text points the model toward `gateway status`. | Prompt projection exposes the `gateway` surface with command hints, while `catalog list --json` shows the source and risk metadata. | -| Review command-route policy | Maintainers inspect route definitions or command catalog entries directly. | `catalog audit --json` groups command paths by route policy key and reports routes without policy keys. | -| Plan routed-operation smoke tests | Maintainers hand-map routed operations to candidate tests. | `catalog test-matrix --json` lists routed-operation smoke candidates and coverage gaps. | -| Operate a paired node | Prompt guidance must be manually updated as node command families are added in PRs such as `gim-home/m#4045`, `#4086`, and `#4088`. | A node-operator prompt lens exposes the available node commands, argument hints, and approval boundaries for the active node context. | - -## Unresolved Questions - -- How much of the command-route policy should be exposed as stable metadata - instead of summarized as route policy keys? -- Should descriptor and command-route counts become explicit compatibility - guards, or should they be treated as expected-to-change inventory counts? -- Where should confirmation thresholds live? -- Are simple metadata gates enough, or is conditional enablement eventually - needed? -- When should OpenClaw add package exports for catalog builders instead of - keeping the external contract on `openclaw catalog ... --json`? -- Should the node-operator lens consume node command metadata from an exported - OpenClaw/Gateway registry, generated command descriptors, or an artifact - produced by the Desktop/Gateway node command stack? diff --git a/rfcs/0016-command-catalog.md b/rfcs/0016-command-catalog.md new file mode 100644 index 00000000..fa177d60 --- /dev/null +++ b/rfcs/0016-command-catalog.md @@ -0,0 +1,386 @@ +--- +title: Command Catalog +authors: + - Gio +created: 2026-07-04 +last_updated: 2026-07-10 +status: draft +issue: +rfc_pr: https://github.com/openclaw/rfcs/pull/32 +--- + +# Proposal: Command Catalog + +## Summary + +Add a read-only command catalog that joins command information OpenClaw already +owns into one structured inventory. The recommended initial surface is +`openclaw commands` with list and exact inspection. A broader +`openclaw catalog` with operational lenses remains a concrete alternative. +Neither option adds a dispatcher, policy engine, runtime hook, or execution +path. + +## Motivation + +OpenClaw command information is distributed across CLI descriptors, command +routes, the runtime Commander tree, plugin CLI descriptors, paired-node command +declarations, and command-like tool adapters. Those sources are useful +independently, but operators and automation currently have no single view that +can answer: + +- what command surfaces exist; +- where each entry came from; +- which entries read or mutate state; +- which entries require confirmation or deserve risk attention; and +- which plugin entries are public inventory versus internal-only metadata. + +Help text is designed for people, not as a stable machine-readable inventory. +Reimplementing the same joins in compliance, diagnostics, tests, and deployment +tools would create drift. A catalog view keeps the existing registries as the +source of truth and performs the join once. + +This is also a practical compliance need. Operators need to enumerate the +command surfaces present in a deployment and consistently identify which ones +read state, mutate state, require confirmation, or carry elevated risk. The +catalog does not enforce those decisions; it makes the facts already owned by +command registries available for review and automation. + +Existing issues show demand for parts of this joined view, although none asks +for this exact CLI: + +- [#52919](https://github.com/openclaw/openclaw/issues/52919) requested runtime + command discovery for remote clients and led to Gateway `commands.list`. +- [#77943](https://github.com/openclaw/openclaw/issues/77943) documents the cost + of inconsistent machine-readable list output for downstream automation. +- [#50011](https://github.com/openclaw/openclaw/issues/50011) shows node command + policy accepting names that do not match the known command inventory. +- [#77730](https://github.com/openclaw/openclaw/issues/77730) shows configured + plugin node commands diverging from the commands advertised at runtime. +- [#98978](https://github.com/openclaw/openclaw/issues/98978) documents command + descriptions drifting across root help, registered help, and completion. +- [#96697](https://github.com/openclaw/openclaw/issues/96697) shows a read-only + node listing accidentally loading plugin CLI/runtime work and becoming much + slower. +- [#89797](https://github.com/openclaw/openclaw/issues/89797) shows a node + capability being advertised without corresponding registered commands. +- [#78082](https://github.com/openclaw/openclaw/issues/78082) shows disabled + native commands remaining registered in an external provider control plane. + +Prompt-related requests show another possible consumer of the same structured +facts. [#14619](https://github.com/openclaw/openclaw/issues/14619) asks to +remove duplicated tool-list prompt text, +[#14785](https://github.com/openclaw/openclaw/issues/14785) tracks broader tool +schema token overhead, and +[#41417](https://github.com/openclaw/openclaw/issues/41417) asks for assembled +prompt inspection. A future scoped projection could derive compact command +guidance from the catalog, but the initial implementation does not claim token +savings or replace tool schemas. + +OpenClaw already exposes a Gateway RPC named `commands.list`. That RPC lists +agent-facing chat, native, skill, and plugin commands for an agent/provider +scope. It does not enumerate CLI routes, the full Commander tree, or paired-node +commands. The naming decision in this RFC must make that distinction clear. +Merging that agent-facing RPC inventory into either option is a possible +follow-up, not part of the initial implementations compared here. + +## Goals + +- Provide a parseable, read-only command inventory through a familiar CLI. +- Preserve existing descriptors, routes, and plugin registries as owners of + command shape and behavior. +- Label entries by source and discovery mode. +- Report effect mode, risk, and confirmation requirements when the owning + source knows them. +- Include the current invocation's Commander tree automatically while keeping + plugin descriptor loading opt-in. +- Support focused inspection without requiring consumers to scrape help text. +- Give future prompt, generated-documentation, compatibility-fixture, + diagnostics, and policy consumers one normalized input. + +## Non-Goals + +- Adding a command dispatcher or expression language. +- Executing commands from catalog records. +- Enforcing policy, permissions, risk, or confirmation in the catalog. +- Producing a signed compliance attestation or tamper-evident audit record. +- Replacing CLI, route, plugin, tool, or node registries. +- Replacing or expanding the Gateway `commands.list` RPC in the initial change. +- Generating agent prompts in the initial implementation. +- Freezing command counts or every advisory output field as a permanent API. +- Requiring schema snapshots, generated docs, or CI report artifacts before the + core catalog shape is accepted. + +## Proposal + +### Naming and scope options + +Both options use existing registries as sources of truth and keep execution in +the current command implementations. + +#### Option A: commands list and inspect (recommended) + +```text +openclaw commands list +openclaw commands inspect +``` + +This option stays command-owned: CLI descriptors, routes, the current Commander +tree, opt-in plugin CLI descriptors, and caller-supplied node command records. +It excludes ownerless tool adapters and aggregate audit/test/summary reports. +`commands` follows existing noun-based CLI groups such as `plugins` and +`skills`, but overlaps conceptually with the narrower Gateway `commands.list` +RPC described above. + +Concrete drafts: + +- [upstream draft](https://github.com/openclaw/openclaw/pull/100960) +- [commands list](https://github.com/giodl73-repo/openclaw/pull/24) +- [commands inspect](https://github.com/giodl73-repo/openclaw/pull/25) +- [optional scoped prompt projection](https://github.com/giodl73-repo/openclaw/pull/26) + +#### Option B: broader catalog + +```text +openclaw catalog list +openclaw catalog audit +openclaw catalog test-matrix +openclaw catalog summary +``` + +This option can include explicit adapters for command-like tool surfaces and +provides audit, test-planning, and operator lenses over the joined inventory. +`catalog` communicates that the result is a read-only cross-registry view, but +introduces a new product noun. + +Concrete drafts: + +- [catalog foundation](https://github.com/giodl73-repo/openclaw/pull/11) +- [dynamic and operator lenses](https://github.com/giodl73-repo/openclaw/pull/12) + +Option A is recommended because it follows existing CLI naming, has a tighter +ownership boundary, and delivers useful list/inspect behavior without requiring +the broader reports. Search, prompt projection, generated docs, and additional +reports can follow after the command inventory contract is accepted. + +### Option B catalog sources + +The catalog joins existing sources rather than introducing a second command +registry: + +- static core and sub-CLI descriptors; +- command paths, route IDs, and startup-policy keys from the existing command + catalog; +- routed operations derived from those route entries; +- the current invocation's registered Commander tree, collected automatically; +- plugin CLI descriptors when the caller explicitly requests them; and +- explicit adapters for tool-backed surfaces that do not yet have an owning + structured descriptor. + +Every normalized entry identifies its source kind, source ID, and discovery +mode. Dynamic data remains labeled as dynamic rather than being presented as a +static compatibility promise. The catalog reports OpenClaw-known inventory; it +does not prove that an external provider such as Discord has reconciled stale +registrations. A future provider-specific collector may add that observed state +as a separately labeled source. + +### Shared minimal source metadata + +Most catalog fields are derived from information registries already own. Two +small optional concepts cover operational facts that cannot be inferred +reliably: + +```ts +type CommandEffectProfile = { + effectMode: "read" | "mutating" | "mixed"; + confirmationRequired?: boolean; + risk?: "low" | "medium" | "high"; +}; + +type CommandExposure = { + tier?: "public" | "internal"; +}; +``` + +`CommandEffectProfile` is advisory metadata. It describes expected behavior but +does not grant permission, bypass confirmation, or replace command validation. +Risk remains separate from effect mode: a read operation can expose sensitive +data, while a local mutation can be low risk. + +An omitted effect profile means `unknown`; it must not be interpreted as read, +low risk, or confirmation-free. Consumers that require complete classification +must report or reject unclassified entries rather than supplying permissive +defaults. + +`CommandExposure` is deliberately not a per-consumer allowlist. `public` means +the entry is suitable for public catalog and documentation views; `internal` +keeps it in audit, operator, and policy inventory by default. Plugin CLI +descriptors may also use their existing descriptor shape to mark a placeholder +`hidden`, causing generated catalog inventory to omit it. + +Prompt-specific command hints are not part of either source type. If a later +prompt consumer is accepted, the catalog lens should derive or own that +presentation metadata. + +Plugin-provided metadata crosses a JavaScript boundary, so OpenClaw validates +effect and exposure values during plugin registration. Invalid or expanded +shapes are discarded instead of entering catalog output. + +### Option B CLI views + +The initial command surface is: + +```text +openclaw catalog list [--json|--markdown] [--plugin-descriptors] +openclaw catalog audit [--json|--markdown] [--plugin-descriptors] +openclaw catalog test-matrix [--json|--markdown] +openclaw catalog summary [--json|--markdown] [--plugin-descriptors] +``` + +`list` returns the joined inventory. `audit` groups entries by risk, effect, +confirmation requirement, and route policy keys. `test-matrix` produces +non-blocking routed-operation test candidates. `summary` provides a compact +operator handoff, including separate medium-risk, high-risk, and +confirmation-required attention. + +Plugin descriptors are opt-in because collecting them loads plugin metadata. +When requested, plugin effect profiles contribute to audit and summary output; +hidden descriptors remain omitted. JSON output remains machine-readable even +if plugin loading emits logs. Collection must use the non-activating metadata +path and must fail visibly when an error would make the requested inventory +incomplete. + +### Stability boundary + +The CLI and JSON output are the external access path for the initial proposal. +Builder modules under `src/` are implementation details unless package exports +are added deliberately later. + +Schema versions, identity fields, provenance, and value kinds are candidates +for stable treatment. Inventory counts and advisory fields should remain +reviewable snapshots because OpenClaw's command and plugin surface changes over +time. A consumer may timestamp, hash, compare, or sign a snapshot, but the +catalog output alone is not an attestation that a command was permitted or that +the deployment remained unchanged after collection. + +### Implementation drafts + +The recommended Option A implementation is available in +[openclaw/openclaw#100960](https://github.com/openclaw/openclaw/pull/100960). +The two initial review layers and two optional follow-ups are available on the +author's fork: + +1. [Commands list](https://github.com/giodl73-repo/openclaw/pull/24): command-owned + static, routed, runtime, plugin, and caller-supplied node inventory. +2. [Commands inspect](https://github.com/giodl73-repo/openclaw/pull/25): exact + inspection with lazy command hydration, aliases, and inherited route metadata. +3. [Scoped prompt projection](https://github.com/giodl73-repo/openclaw/pull/26): + optional command-only model guidance, reviewed separately from the initial CLI. +4. [Generated command reference](https://github.com/giodl73-repo/openclaw/pull/28): + optional command-only docs generation and freshness guard, reviewed separately + from the initial CLI. + +The broader Option B remains preserved in fork drafts for comparison: + +1. [Catalog foundation](https://github.com/giodl73-repo/openclaw/pull/11). +2. [Dynamic/operator lenses](https://github.com/giodl73-repo/openclaw/pull/12). +3. [Prompt projection](https://github.com/giodl73-repo/openclaw/pull/13): a + compact, scoped model-facing lens. +4. [Schema fixtures](https://github.com/giodl73-repo/openclaw/pull/14): + reviewable snapshots for stable IDs and output shape. +5. [Generated reference docs](https://github.com/giodl73-repo/openclaw/pull/15): + documentation generated from the catalog API. +6. [Hardening and consumer contract](https://github.com/giodl73-repo/openclaw/pull/16): + an archived prototype of richer advisory artifacts and downstream boundaries. + +### Future documentation automation + +The earlier [generated reference draft](https://github.com/giodl73-repo/openclaw/pull/15) +is a prototype, not a claim that every OpenClaw CLI document was generated or +reconciled. It produced one reference page plus navigation, docs-map, glossary, +and freshness wiring. + +If documentation automation follows the initial command inventory, it should: + +- generate one checked-in `/cli/commands` reference from static command-owned + inventory, with matching `--write` and `--check` commands; +- add a contract test that compares canonical descriptions across root help, + registered command help, completion, and catalog output, addressing the drift + demonstrated by [#98978](https://github.com/openclaw/openclaw/issues/98978); +- keep workflow and conceptual pages hand-authored, linking them to the + generated reference instead of rewriting explanatory documentation; +- keep Plugin SDK semantics and compatibility guidance hand-authored; and +- exclude deployment-specific plugin, node, and external-provider observations + from checked-in snapshots while documenting how operators can inspect them at + runtime. + +The command-only implementation of this first layer is available in +[fork PR #28](https://github.com/giodl73-repo/openclaw/pull/28). It is the +exemplar for generating one static reference and enforcing freshness; it does +not implement every follow-up below. + +Possible documentation follow-ups, each independently reviewable, are: + +1. **Public command page coverage.** Compare public static commands with + `docs/cli/*` and require each command to declare a dedicated page, an alias + target, or an explicit index-only classification. This catches a newly added + command with no documentation destination. +2. **Subcommand and option references.** Generate compact command trees and + option summaries from registered Commander metadata. Hand-authored command + pages should embed or link those references while retaining authored + examples, workflows, safety notes, and conceptual guidance. +3. **Runtime inventory guidance.** Document how operators export + deployment-specific plugin descriptors with + `openclaw commands list --json --plugin-descriptors`, including the + completeness and external-provider boundaries described above. After a live + paired-node collector exists, extend that guidance with its separately + labeled node observations. Dynamic results should not become canonical + checked-in OpenClaw docs. + +This sequence intentionally avoids generated explanatory prose. Automation +owns inventory, structural coverage, and freshness; maintainers continue to own +behavioral guidance and compatibility commitments. + +The recommended drafts intentionally keep node commands in the object model as +caller-supplied records. Connecting live paired-node inventory and reconciling +the Gateway `commands.list` agent view are separate follow-up integrations. + +The required OpenClaw `maintainer-discussion` thread must be created and linked +before acceptance. The RFC remains in `draft` status until maintainers accept +it. Namespace, stable schema, plugin metadata, and Gateway convergence remain +maintainer decisions rather than contributor-declared contracts. + +## Rationale + +The main alternative is a new typed operation or DSL layer. That could make +mechanical operations explicit, but it would also create a second execution +surface that could drift from existing CLI and tool behavior. A read-only view +is lower risk: every record points back to a current owner, and execution stays +where it already works. + +Another alternative is to expose only help text or the Commander tree. That +would miss route-policy metadata, plugin provenance, tool-backed surfaces, and +effect/confirmation facts. It would also encourage consumers to scrape display +text. + +Both options perform the hard N-to-1 normalization in one layer while keeping +source additions small. Option A favors familiar CLI naming and a tighter +command-only boundary. Option B favors a distinct name and broader lenses. The +concrete drafts make that tradeoff reviewable before the public name and JSON +contract are accepted. + +## Unresolved questions + +- Which JSON fields should be stable in the first supported contract beyond + schema version, identity, and provenance? +- Should plugin descriptor collection remain an explicit flag permanently, or + can a future lifecycle-owned metadata cache make it safe by default? +- Should `CommandExposure` be accepted as plugin-facing API now, or remain an + experimental optional field until another consumer adopts it? +- Which additional routed operations need explicit effect profiles rather than + conservative catalog defaults? +- If prompt generation is proposed later, which catalog fields should be + derived for that lens without expanding source registry metadata? +- Should the public CLI use `catalog` to distinguish this cross-registry view, + or `commands` to match existing noun-based CLI groups? +- If `commands` is chosen, how should its CLI inventory relate to the existing + Gateway `commands.list` RPC for agent-facing commands? From ac889d4843e9829acd8f5b13b44ca2b2371f0cd2 Mon Sep 17 00:00:00 2001 From: Gio Della-Libera Date: Fri, 10 Jul 2026 18:13:02 -0700 Subject: [PATCH 22/26] Document live node command follow-up --- rfcs/0016-command-catalog.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/rfcs/0016-command-catalog.md b/rfcs/0016-command-catalog.md index fa177d60..9e04f57a 100644 --- a/rfcs/0016-command-catalog.md +++ b/rfcs/0016-command-catalog.md @@ -266,7 +266,7 @@ the deployment remained unchanged after collection. The recommended Option A implementation is available in [openclaw/openclaw#100960](https://github.com/openclaw/openclaw/pull/100960). -The two initial review layers and two optional follow-ups are available on the +The two initial review layers and three optional follow-ups are available on the author's fork: 1. [Commands list](https://github.com/giodl73-repo/openclaw/pull/24): command-owned @@ -278,6 +278,10 @@ author's fork: 4. [Generated command reference](https://github.com/giodl73-repo/openclaw/pull/28): optional command-only docs generation and freshness guard, reviewed separately from the initial CLI. +5. [Live paired-node commands](https://github.com/giodl73-repo/openclaw/pull/29): + optional `node.describe` collection for one connected paired node, labeled as + timestamped, identifier-only runtime observations and accepted by the scoped + node-operator projection. The broader Option B remains preserved in fork drafts for comparison: @@ -340,9 +344,13 @@ This sequence intentionally avoids generated explanatory prose. Automation owns inventory, structural coverage, and freshness; maintainers continue to own behavioral guidance and compatibility commitments. -The recommended drafts intentionally keep node commands in the object model as -caller-supplied records. Connecting live paired-node inventory and reconciling -the Gateway `commands.list` agent view are separate follow-up integrations. +The initial recommended drafts keep node commands in the object model as +caller-supplied records. The optional live-node draft connects one selected +paired node through the existing Gateway `node.describe` method without adding a +new node protocol. It fails when the node is disconnected and does not invent +descriptions, argument schemas, or semantic effects that the node handshake does +not provide. Reconciling the Gateway `commands.list` agent view remains a +separate follow-up integration. The required OpenClaw `maintainer-discussion` thread must be created and linked before acceptance. The RFC remains in `draft` status until maintainers accept From c8c0ee8472989a4993b199f82d2f4360ba994f82 Mon Sep 17 00:00:00 2001 From: Gio Della-Libera Date: Fri, 10 Jul 2026 23:00:42 -0700 Subject: [PATCH 23/26] RFC: add command catalog consumer drafts --- rfcs/0016-command-catalog.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/rfcs/0016-command-catalog.md b/rfcs/0016-command-catalog.md index 9e04f57a..47cddbbd 100644 --- a/rfcs/0016-command-catalog.md +++ b/rfcs/0016-command-catalog.md @@ -283,6 +283,26 @@ author's fork: timestamped, identifier-only runtime observations and accepted by the scoped node-operator projection. +Three additional consumer drafts demonstrate how the same inventory can support +enterprise and agent workflows without expanding the initial catalog contract: + +6. [Policy evidence projection](https://github.com/giodl73-repo/openclaw/pull/30): + deterministic records for policy and compliance collectors. The projection + preserves source and observation scope and explicitly identifies itself as + inventory evidence, not a signed attestation or policy decision. +7. [Runtime inventory comparison](https://github.com/giodl73-repo/openclaw/pull/31): + an advisory comparison of two inventory snapshots, reporting added, removed, + changed, and scope-changed records. It describes OpenClaw-observed drift only; + it does not infer an external control-plane change or policy violation. +8. [Bounded command search](https://github.com/giodl73-repo/openclaw/pull/32): + compact search results plus exact-record hydration for progressive disclosure. + Results are non-executable command metadata, are capped at 20 entries, and + avoid placing the complete command directory in every model prompt. + +These are optional follow-ups, not acceptance requirements for `commands list` +or `commands inspect`. They consume the normalized inventory and add no command +registry fields, dispatcher, execution path, policy engine, or new CLI namespace. + The broader Option B remains preserved in fork drafts for comparison: 1. [Catalog foundation](https://github.com/giodl73-repo/openclaw/pull/11). From 362e497a5a39715e6232b07bef431c304eef326e Mon Sep 17 00:00:00 2001 From: Gio Della-Libera Date: Sat, 11 Jul 2026 14:16:27 -0700 Subject: [PATCH 24/26] RFC: renumber command catalog to 0017 --- rfcs/{0016-command-catalog.md => 0017-command-catalog.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename rfcs/{0016-command-catalog.md => 0017-command-catalog.md} (99%) diff --git a/rfcs/0016-command-catalog.md b/rfcs/0017-command-catalog.md similarity index 99% rename from rfcs/0016-command-catalog.md rename to rfcs/0017-command-catalog.md index 47cddbbd..02c95111 100644 --- a/rfcs/0016-command-catalog.md +++ b/rfcs/0017-command-catalog.md @@ -3,7 +3,7 @@ title: Command Catalog authors: - Gio created: 2026-07-04 -last_updated: 2026-07-10 +last_updated: 2026-07-11 status: draft issue: rfc_pr: https://github.com/openclaw/rfcs/pull/32 From c1bedc053ef74a2212b493444bc0bbe89e9e6257 Mon Sep 17 00:00:00 2001 From: Gio Della-Libera Date: Thu, 23 Jul 2026 09:40:52 -0700 Subject: [PATCH 25/26] docs(rfc): tighten command catalog contract --- rfcs/0017-command-catalog.md | 566 ++++++++++++++--------------------- 1 file changed, 217 insertions(+), 349 deletions(-) diff --git a/rfcs/0017-command-catalog.md b/rfcs/0017-command-catalog.md index 02c95111..ffd3a8de 100644 --- a/rfcs/0017-command-catalog.md +++ b/rfcs/0017-command-catalog.md @@ -3,7 +3,7 @@ title: Command Catalog authors: - Gio created: 2026-07-04 -last_updated: 2026-07-11 +last_updated: 2026-07-23 status: draft issue: rfc_pr: https://github.com/openclaw/rfcs/pull/32 @@ -13,181 +13,118 @@ rfc_pr: https://github.com/openclaw/rfcs/pull/32 ## Summary -Add a read-only command catalog that joins command information OpenClaw already -owns into one structured inventory. The recommended initial surface is -`openclaw commands` with list and exact inspection. A broader -`openclaw catalog` with operational lenses remains a concrete alternative. -Neither option adds a dispatcher, policy engine, runtime hook, or execution -path. +Add a read-only command catalog through `openclaw commands list` and +`openclaw commands inspect`. It joins command information OpenClaw already owns +without adding a dispatcher, policy engine, runtime hook, or execution path. + +The catalog reports known command metadata available to the current invocation. +It identifies which sources were collected and preserves unknown operational +effects instead of turning missing classifications into permissive facts. ## Motivation -OpenClaw command information is distributed across CLI descriptors, command -routes, the runtime Commander tree, plugin CLI descriptors, paired-node command -declarations, and command-like tool adapters. Those sources are useful -independently, but operators and automation currently have no single view that -can answer: - -- what command surfaces exist; -- where each entry came from; -- which entries read or mutate state; -- which entries require confirmation or deserve risk attention; and -- which plugin entries are public inventory versus internal-only metadata. - -Help text is designed for people, not as a stable machine-readable inventory. -Reimplementing the same joins in compliance, diagnostics, tests, and deployment -tools would create drift. A catalog view keeps the existing registries as the -source of truth and performs the join once. - -This is also a practical compliance need. Operators need to enumerate the -command surfaces present in a deployment and consistently identify which ones -read state, mutate state, require confirmation, or carry elevated risk. The -catalog does not enforce those decisions; it makes the facts already owned by -command registries available for review and automation. - -Existing issues show demand for parts of this joined view, although none asks -for this exact CLI: - -- [#52919](https://github.com/openclaw/openclaw/issues/52919) requested runtime - command discovery for remote clients and led to Gateway `commands.list`. +OpenClaw command information is distributed across static CLI descriptors, +command routes, the runtime Commander tree, plugin CLI descriptors, and paired +nodes. Help text is useful for people but is not a stable machine-readable +inventory. Reimplementing these joins in compliance, diagnostics, +documentation, and prompt consumers would create drift. + +Operators and compliance tooling need a consistent way to review: + +- which known command surfaces were included in an observation; +- where each record came from; +- which commands are classified as reading or mutating state; +- which commands declare confirmation or elevated risk; and +- which entries are public, internal, hidden, static, or runtime-observed. + +The result is inventory evidence, not proof that every possible lazy or external +surface was observed, not a signed attestation, and not an authorization +decision. + +Existing issues show demand for parts of this joined view: + +- [#52919](https://github.com/openclaw/openclaw/issues/52919) led to Gateway + `commands.list` for remote agent-command discovery. - [#77943](https://github.com/openclaw/openclaw/issues/77943) documents the cost - of inconsistent machine-readable list output for downstream automation. -- [#50011](https://github.com/openclaw/openclaw/issues/50011) shows node command - policy accepting names that do not match the known command inventory. -- [#77730](https://github.com/openclaw/openclaw/issues/77730) shows configured - plugin node commands diverging from the commands advertised at runtime. + of inconsistent machine-readable list output. +- [#50011](https://github.com/openclaw/openclaw/issues/50011) and + [#77730](https://github.com/openclaw/openclaw/issues/77730) show node command + policy or configuration diverging from runtime-advertised commands. - [#98978](https://github.com/openclaw/openclaw/issues/98978) documents command - descriptions drifting across root help, registered help, and completion. -- [#96697](https://github.com/openclaw/openclaw/issues/96697) shows a read-only - node listing accidentally loading plugin CLI/runtime work and becoming much - slower. + descriptions drifting across help and completion surfaces. +- [#96697](https://github.com/openclaw/openclaw/issues/96697) shows why plugin + collection should remain explicit for read-only listings. - [#89797](https://github.com/openclaw/openclaw/issues/89797) shows a node - capability being advertised without corresponding registered commands. -- [#78082](https://github.com/openclaw/openclaw/issues/78082) shows disabled - native commands remaining registered in an external provider control plane. - -Prompt-related requests show another possible consumer of the same structured -facts. [#14619](https://github.com/openclaw/openclaw/issues/14619) asks to -remove duplicated tool-list prompt text, -[#14785](https://github.com/openclaw/openclaw/issues/14785) tracks broader tool -schema token overhead, and -[#41417](https://github.com/openclaw/openclaw/issues/41417) asks for assembled -prompt inspection. A future scoped projection could derive compact command -guidance from the catalog, but the initial implementation does not claim token -savings or replace tool schemas. - -OpenClaw already exposes a Gateway RPC named `commands.list`. That RPC lists -agent-facing chat, native, skill, and plugin commands for an agent/provider -scope. It does not enumerate CLI routes, the full Commander tree, or paired-node -commands. The naming decision in this RFC must make that distinction clear. -Merging that agent-facing RPC inventory into either option is a possible -follow-up, not part of the initial implementations compared here. + capability advertised without corresponding registered commands. +- [#78082](https://github.com/openclaw/openclaw/issues/78082) shows stale + external-provider registrations. + +Prompt-related issues [#14619](https://github.com/openclaw/openclaw/issues/14619), +[#14785](https://github.com/openclaw/openclaw/issues/14785), and +[#41417](https://github.com/openclaw/openclaw/issues/41417) motivate an optional, +explicitly scoped projection. They do not make prompt generation part of the +initial catalog contract or establish a token-savings claim. ## Goals - Provide a parseable, read-only command inventory through a familiar CLI. -- Preserve existing descriptors, routes, and plugin registries as owners of - command shape and behavior. -- Label entries by source and discovery mode. -- Report effect mode, risk, and confirmation requirements when the owning - source knows them. -- Include the current invocation's Commander tree automatically while keeping - plugin descriptor loading opt-in. -- Support focused inspection without requiring consumers to scrape help text. -- Give future prompt, generated-documentation, compatibility-fixture, - diagnostics, and policy consumers one normalized input. +- Keep existing descriptors, routes, Commander registrations, plugins, and + nodes as the owners of command facts. +- Label records by source, discovery mode, visibility, and collection scope. +- Report effect, risk, and confirmation metadata only when an owning source + declares it. +- Support exact inspection without scraping help text. +- Give later documentation, diagnostics, prompt, and policy consumers one + normalized input. ## Non-Goals -- Adding a command dispatcher or expression language. -- Executing commands from catalog records. -- Enforcing policy, permissions, risk, or confirmation in the catalog. -- Producing a signed compliance attestation or tamper-evident audit record. -- Replacing CLI, route, plugin, tool, or node registries. -- Replacing or expanding the Gateway `commands.list` RPC in the initial change. -- Generating agent prompts in the initial implementation. -- Freezing command counts or every advisory output field as a permanent API. -- Requiring schema snapshots, generated docs, or CI report artifacts before the - core catalog shape is accepted. +- Adding a command dispatcher, expression language, or alternate execution API. +- Enforcing permissions, policy, risk, or confirmation. +- Producing a signed compliance attestation. +- Claiming that current-invocation, opt-in plugin, node, or external-provider + observations are globally complete. +- Replacing CLI, route, plugin, node, or Gateway registries. +- Replacing or expanding Gateway `commands.list` in the initial change. +- Enabling command guidance in every agent prompt by default. +- Freezing command counts. ## Proposal -### Naming and scope options - -Both options use existing registries as sources of truth and keep execution in -the current command implementations. - -#### Option A: commands list and inspect (recommended) +### CLI surface ```text -openclaw commands list -openclaw commands inspect +openclaw commands list [--json|--markdown] [--plugin-descriptors] +openclaw commands list [--json|--markdown] --node +openclaw commands inspect [--json|--markdown] ``` -This option stays command-owned: CLI descriptors, routes, the current Commander -tree, opt-in plugin CLI descriptors, and caller-supplied node command records. -It excludes ownerless tool adapters and aggregate audit/test/summary reports. -`commands` follows existing noun-based CLI groups such as `plugins` and -`skills`, but overlaps conceptually with the narrower Gateway `commands.list` -RPC described above. +`list` joins static descriptors, command routes, routed operations, the +currently registered Commander tree, explicitly requested plugin descriptors, +and explicitly requested or caller-supplied node observations. `inspect` +hydrates the requested lazy command group and returns exact matching records, +including aliases and inherited route metadata. -Concrete drafts: +The JSON result includes collection status for each source. Callers can +distinguish not requested, collected, complete static input, current-invocation +runtime input, and node observation scope. Counts are descriptive and +non-normative. -- [upstream draft](https://github.com/openclaw/openclaw/pull/100960) -- [commands list](https://github.com/giodl73-repo/openclaw/pull/24) -- [commands inspect](https://github.com/giodl73-repo/openclaw/pull/25) -- [optional scoped prompt projection](https://github.com/giodl73-repo/openclaw/pull/26) +The `commands` root becomes a core-reserved CLI group. Plugins may contribute +through existing supported registration points but do not replace a core root +command. Registration precedence remains owned by the existing CLI registry. -#### Option B: broader catalog - -```text -openclaw catalog list -openclaw catalog audit -openclaw catalog test-matrix -openclaw catalog summary -``` +### Existing Gateway surface -This option can include explicit adapters for command-like tool surfaces and -provides audit, test-planning, and operator lenses over the joined inventory. -`catalog` communicates that the result is a read-only cross-registry view, but -introduces a new product noun. +Gateway `commands.list` remains the agent/provider-scoped view of chat, native, +skill, and plugin commands. The proposed CLI is an operator/developer view of +CLI, route, runtime, plugin-CLI, and selected node records. Neither calls nor +replaces the other. A future integration may normalize Gateway results as an +additional labeled source. -Concrete drafts: +### Source metadata -- [catalog foundation](https://github.com/giodl73-repo/openclaw/pull/11) -- [dynamic and operator lenses](https://github.com/giodl73-repo/openclaw/pull/12) - -Option A is recommended because it follows existing CLI naming, has a tighter -ownership boundary, and delivers useful list/inspect behavior without requiring -the broader reports. Search, prompt projection, generated docs, and additional -reports can follow after the command inventory contract is accepted. - -### Option B catalog sources - -The catalog joins existing sources rather than introducing a second command -registry: - -- static core and sub-CLI descriptors; -- command paths, route IDs, and startup-policy keys from the existing command - catalog; -- routed operations derived from those route entries; -- the current invocation's registered Commander tree, collected automatically; -- plugin CLI descriptors when the caller explicitly requests them; and -- explicit adapters for tool-backed surfaces that do not yet have an owning - structured descriptor. - -Every normalized entry identifies its source kind, source ID, and discovery -mode. Dynamic data remains labeled as dynamic rather than being presented as a -static compatibility promise. The catalog reports OpenClaw-known inventory; it -does not prove that an external provider such as Discord has reconciled stale -registrations. A future provider-specific collector may add that observed state -as a separately labeled source. - -### Shared minimal source metadata - -Most catalog fields are derived from information registries already own. Two -small optional concepts cover operational facts that cannot be inferred -reliably: +Two small optional concepts cover facts that cannot be inferred reliably: ```ts type CommandEffectProfile = { @@ -201,214 +138,145 @@ type CommandExposure = { }; ``` -`CommandEffectProfile` is advisory metadata. It describes expected behavior but -does not grant permission, bypass confirmation, or replace command validation. -Risk remains separate from effect mode: a read operation can expose sensitive -data, while a local mutation can be low risk. +Effect metadata is advisory and does not grant permission. An omitted value is +`unknown`; inventory and evidence consumers must not convert it to read-only, +low-risk, or confirmation-free. A prompt projection may apply a separately +labeled conservative presentation fallback, such as unknown risk plus required +confirmation, without changing the source-owned record. -An omitted effect profile means `unknown`; it must not be interpreted as read, -low risk, or confirmation-free. Consumers that require complete classification -must report or reject unclassified entries rather than supplying permissive -defaults. +`public` records may appear in public list and generated-documentation views. +`internal` records remain available to operator, audit, and policy consumers. +Existing hidden descriptors are omitted from public inventory and generated +documentation. -`CommandExposure` is deliberately not a per-consumer allowlist. `public` means -the entry is suitable for public catalog and documentation views; `internal` -keeps it in audit, operator, and policy inventory by default. Plugin CLI -descriptors may also use their existing descriptor shape to mark a placeholder -`hidden`, causing generated catalog inventory to omit it. +Plugin-provided values cross a JavaScript boundary and are validated during +registration. Invalid or expanded shapes are discarded. The three optional +plugin descriptor fields are `effectProfile`, `commandExposure`, and `hidden`. -Prompt-specific command hints are not part of either source type. If a later -prompt consumer is accepted, the catalog lens should derive or own that -presentation metadata. +### Plugin collection boundary -Plugin-provided metadata crosses a JavaScript boundary, so OpenClaw validates -effect and exposure values during plugin registration. Invalid or expanded -shapes are discarded instead of entering catalog output. +`--plugin-descriptors` is explicit because collection imports and executes +enabled, trusted plugin modules in a restricted metadata-registration mode. +Disabling OpenClaw runtime activation side effects does not make arbitrary +module top-level code inert. Requested collection fails visibly on loader +exceptions or error diagnostics so an incomplete result is not presented as +complete. Plugin logs are routed away from machine-readable stdout. -### Option B CLI views +### Node observations -The initial command surface is: +`--node` reuses the pairing-aware diagnostics path for Gateway `node.describe`. +It adds no protocol method or node registry. The selected node must be connected +and must identify itself as the requested node. -```text -openclaw catalog list [--json|--markdown] [--plugin-descriptors] -openclaw catalog audit [--json|--markdown] [--plugin-descriptors] -openclaw catalog test-matrix [--json|--markdown] -openclaw catalog summary [--json|--markdown] [--plugin-descriptors] -``` +The handshake supplies command identifiers, not descriptions, argument schemas, +approval state, availability guarantees, or semantic effects. Live records +therefore remain identifier-only with unknown semantics. Command identifiers +must match a strict bounded grammar before they can enter a model-facing +projection. Rejected identifiers may still be reported separately by a future +audit collector, but are never prompt instructions. -`list` returns the joined inventory. `audit` groups entries by risk, effect, -confirmation requirement, and route policy keys. `test-matrix` produces -non-blocking routed-operation test candidates. `summary` provides a compact -operator handoff, including separate medium-risk, high-risk, and -confirmation-required attention. - -Plugin descriptors are opt-in because collecting them loads plugin metadata. -When requested, plugin effect profiles contribute to audit and summary output; -hidden descriptors remain omitted. JSON output remains machine-readable even -if plugin loading emits logs. Collection must use the non-activating metadata -path and must fail visibly when an error would make the requested inventory -incomplete. +An explicitly opted-in `node-operator` projection may render a validated node +identifier and the existing `nodes action=invoke` routing shape. It does not +invent `{}` parameters when no argument schema is available, and unknown +effects receive conservative prompt guidance rather than permissive defaults. ### Stability boundary -The CLI and JSON output are the external access path for the initial proposal. -Builder modules under `src/` are implementation details unless package exports -are added deliberately later. - -Schema versions, identity fields, provenance, and value kinds are candidates -for stable treatment. Inventory counts and advisory fields should remain -reviewable snapshots because OpenClaw's command and plugin surface changes over -time. A consumer may timestamp, hash, compare, or sign a snapshot, but the -catalog output alone is not an attestation that a command was permitted or that -the deployment remained unchanged after collection. - -### Implementation drafts - -The recommended Option A implementation is available in -[openclaw/openclaw#100960](https://github.com/openclaw/openclaw/pull/100960). -The two initial review layers and three optional follow-ups are available on the -author's fork: - -1. [Commands list](https://github.com/giodl73-repo/openclaw/pull/24): command-owned - static, routed, runtime, plugin, and caller-supplied node inventory. -2. [Commands inspect](https://github.com/giodl73-repo/openclaw/pull/25): exact - inspection with lazy command hydration, aliases, and inherited route metadata. -3. [Scoped prompt projection](https://github.com/giodl73-repo/openclaw/pull/26): - optional command-only model guidance, reviewed separately from the initial CLI. -4. [Generated command reference](https://github.com/giodl73-repo/openclaw/pull/28): - optional command-only docs generation and freshness guard, reviewed separately - from the initial CLI. -5. [Live paired-node commands](https://github.com/giodl73-repo/openclaw/pull/29): - optional `node.describe` collection for one connected paired node, labeled as - timestamped, identifier-only runtime observations and accepted by the scoped - node-operator projection. - -Three additional consumer drafts demonstrate how the same inventory can support -enterprise and agent workflows without expanding the initial catalog contract: - -6. [Policy evidence projection](https://github.com/giodl73-repo/openclaw/pull/30): - deterministic records for policy and compliance collectors. The projection - preserves source and observation scope and explicitly identifies itself as - inventory evidence, not a signed attestation or policy decision. -7. [Runtime inventory comparison](https://github.com/giodl73-repo/openclaw/pull/31): - an advisory comparison of two inventory snapshots, reporting added, removed, - changed, and scope-changed records. It describes OpenClaw-observed drift only; - it does not infer an external control-plane change or policy violation. -8. [Bounded command search](https://github.com/giodl73-repo/openclaw/pull/32): - compact search results plus exact-record hydration for progressive disclosure. - Results are non-executable command metadata, are capped at 20 entries, and - avoid placing the complete command directory in every model prompt. - -These are optional follow-ups, not acceptance requirements for `commands list` -or `commands inspect`. They consume the normalized inventory and add no command -registry fields, dispatcher, execution path, policy engine, or new CLI namespace. - -The broader Option B remains preserved in fork drafts for comparison: - -1. [Catalog foundation](https://github.com/giodl73-repo/openclaw/pull/11). -2. [Dynamic/operator lenses](https://github.com/giodl73-repo/openclaw/pull/12). -3. [Prompt projection](https://github.com/giodl73-repo/openclaw/pull/13): a - compact, scoped model-facing lens. -4. [Schema fixtures](https://github.com/giodl73-repo/openclaw/pull/14): - reviewable snapshots for stable IDs and output shape. -5. [Generated reference docs](https://github.com/giodl73-repo/openclaw/pull/15): - documentation generated from the catalog API. -6. [Hardening and consumer contract](https://github.com/giodl73-repo/openclaw/pull/16): - an archived prototype of richer advisory artifacts and downstream boundaries. - -### Future documentation automation - -The earlier [generated reference draft](https://github.com/giodl73-repo/openclaw/pull/15) -is a prototype, not a claim that every OpenClaw CLI document was generated or -reconciled. It produced one reference page plus navigation, docs-map, glossary, -and freshness wiring. - -If documentation automation follows the initial command inventory, it should: - -- generate one checked-in `/cli/commands` reference from static command-owned - inventory, with matching `--write` and `--check` commands; -- add a contract test that compares canonical descriptions across root help, - registered command help, completion, and catalog output, addressing the drift - demonstrated by [#98978](https://github.com/openclaw/openclaw/issues/98978); -- keep workflow and conceptual pages hand-authored, linking them to the - generated reference instead of rewriting explanatory documentation; -- keep Plugin SDK semantics and compatibility guidance hand-authored; and -- exclude deployment-specific plugin, node, and external-provider observations - from checked-in snapshots while documenting how operators can inspect them at - runtime. - -The command-only implementation of this first layer is available in -[fork PR #28](https://github.com/giodl73-repo/openclaw/pull/28). It is the -exemplar for generating one static reference and enforcing freshness; it does -not implement every follow-up below. - -Possible documentation follow-ups, each independently reviewable, are: - -1. **Public command page coverage.** Compare public static commands with - `docs/cli/*` and require each command to declare a dedicated page, an alias - target, or an explicit index-only classification. This catches a newly added - command with no documentation destination. -2. **Subcommand and option references.** Generate compact command trees and - option summaries from registered Commander metadata. Hand-authored command - pages should embed or link those references while retaining authored - examples, workflows, safety notes, and conceptual guidance. -3. **Runtime inventory guidance.** Document how operators export - deployment-specific plugin descriptors with - `openclaw commands list --json --plugin-descriptors`, including the - completeness and external-provider boundaries described above. After a live - paired-node collector exists, extend that guidance with its separately - labeled node observations. Dynamic results should not become canonical - checked-in OpenClaw docs. - -This sequence intentionally avoids generated explanatory prose. Automation -owns inventory, structural coverage, and freshness; maintainers continue to own -behavioral guidance and compatibility commitments. - -The initial recommended drafts keep node commands in the object model as -caller-supplied records. The optional live-node draft connects one selected -paired node through the existing Gateway `node.describe` method without adding a -new node protocol. It fails when the node is disconnected and does not invent -descriptions, argument schemas, or semantic effects that the node handshake does -not provide. Reconciling the Gateway `commands.list` agent view remains a -separate follow-up integration. - -The required OpenClaw `maintainer-discussion` thread must be created and linked -before acceptance. The RFC remains in `draft` status until maintainers accept -it. Namespace, stable schema, plugin metadata, and Gateway convergence remain -maintainer decisions rather than contributor-declared contracts. - -## Rationale - -The main alternative is a new typed operation or DSL layer. That could make -mechanical operations explicit, but it would also create a second execution -surface that could drift from existing CLI and tool behavior. A read-only view -is lower risk: every record points back to a current owner, and execution stays -where it already works. - -Another alternative is to expose only help text or the Commander tree. That -would miss route-policy metadata, plugin provenance, tool-backed surfaces, and -effect/confirmation facts. It would also encourage consumers to scrape display -text. - -Both options perform the hard N-to-1 normalization in one layer while keeping -source additions small. Option A favors familiar CLI naming and a tighter -command-only boundary. Option B favors a distinct name and broader lenses. The -concrete drafts make that tradeoff reviewable before the public name and JSON -contract are accepted. - -## Unresolved questions - -- Which JSON fields should be stable in the first supported contract beyond - schema version, identity, and provenance? +The CLI and versioned JSON output are the supported external access paths. +Internal builders remain implementation details unless exported deliberately. + +For schema version 1, stable fields are the schema version, record identity, +source/provenance, discovery mode, collection status, and documented enum value +kinds. New optional fields may be added compatibly. Removing or renaming a +stable field, changing its meaning, or narrowing an accepted enum requires a +schema-version change. Ordering is deterministic. Counts and the set of +commands are not stable compatibility promises. + +Plugin metadata remains optional but follows the same validation and +unknown-preservation rules once emitted. + +## Acceptance Criteria + +- `commands list` and `commands inspect` execute no catalog record. +- Omitted effect metadata remains omitted or explicitly unknown in JSON, + Markdown, evidence, and prompt inputs. +- Output reports whether runtime, plugin, and node sources were collected. +- Hidden descriptors do not enter public list or generated-documentation views. +- Requested plugin collection executes only enabled, trusted modules in the + documented restricted mode and fails on incomplete error-level collection. +- Live node records use the established diagnostics authentication path, + validate identifiers, and remain identifier-only unless an owner supplies + richer metadata. +- Prompt projection is caller-opted-in, tool- and scope-gated, bounded, and + excludes unsafe identifiers. +- Generated documentation uses only static public metadata, and every canonical + generator input schedules or runs its freshness check. +- Each implementation slice type-checks and tests independently of later slices. + +## Implementation Drafts + +The active upstream implementation is split into independently reviewable +slices: + +1. [Foundation #100960](https://github.com/openclaw/openclaw/pull/100960): + `commands list` and exact `commands inspect`, normalized metadata, collection + status, and opt-in plugin descriptors. +2. [Live node inventory #104158](https://github.com/openclaw/openclaw/pull/104158): + pairing-aware `node.describe` collection for one connected node. +3. [Scoped prompt projection #104159](https://github.com/openclaw/openclaw/pull/104159): + explicit run-scoped command guidance, including bounded `node-operator` + records. +4. [Generated reference #104160](https://github.com/openclaw/openclaw/pull/104160): + checked-in static command reference and freshness guard. + +Additional fork drafts are internal prototypes, not public or callable surfaces +and not acceptance requirements for the initial CLI: + +- [Policy evidence #30](https://github.com/giodl73-repo/openclaw/pull/30) + projects normalized, non-attesting records with collection scope. +- [Runtime drift #31](https://github.com/giodl73-repo/openclaw/pull/31) + compares semantic records and collection scope while ignoring observation + timestamps. +- [Bounded search #32](https://github.com/giodl73-repo/openclaw/pull/32) + prototypes compact search and exact hydration, including runtime commands. + +Historical comparison drafts +[Option A #24-#29](https://github.com/giodl73-repo/openclaw/pulls?q=is%3Apr+is%3Aopen+24+25+26+28+29) +and broader catalog drafts +[#11-#16](https://github.com/giodl73-repo/openclaw/pulls?q=is%3Apr+11+12+13+14+15+16) +remain implementation history rather than normative specification. + +## Documentation Automation + +The generated reference covers static public command names, descriptions, +provenance, and declared effects. It deliberately excludes deployment-specific +plugin and node observations. Workflow, examples, SDK semantics, and safety +guidance remain hand-authored. + +Possible later slices may add public-page coverage checks, generated nested +subcommand and option references, and runtime-inventory guidance. Those should +consume the same catalog rather than create another command registry. + +## Alternatives + +A broader `openclaw catalog` prototype included audit, summary, test-matrix, and +ownerless tool adapters. It was rejected as the initial proposal because it +introduced a larger product noun and mixed command inventory with advisory +reports before the base contract was accepted. + +Another alternative is a typed operation or DSL layer. That would create a +second execution surface that could drift from existing CLI and tool behavior. +This proposal stays read-only and points every fact back to an existing owner. + +## Unresolved Questions + - Should plugin descriptor collection remain an explicit flag permanently, or - can a future lifecycle-owned metadata cache make it safe by default? -- Should `CommandExposure` be accepted as plugin-facing API now, or remain an - experimental optional field until another consumer adopts it? -- Which additional routed operations need explicit effect profiles rather than - conservative catalog defaults? -- If prompt generation is proposed later, which catalog fields should be - derived for that lens without expanding source registry metadata? -- Should the public CLI use `catalog` to distinguish this cross-registry view, - or `commands` to match existing noun-based CLI groups? -- If `commands` is chosen, how should its CLI inventory relate to the existing - Gateway `commands.list` RPC for agent-facing commands? + can a future lifecycle-owned metadata cache avoid repeated trusted-module + execution? +- Should Gateway `commands.list` eventually become another labeled catalog + source, or remain an intentionally separate agent/provider view? +- Which routed operations should owners classify next with explicit effect + metadata? + +The required OpenClaw `maintainer-discussion` thread must be linked before RFC +acceptance. From de477188c9e635e1707bfcbc5610e19a16133065 Mon Sep 17 00:00:00 2001 From: Gio Della-Libera Date: Tue, 28 Jul 2026 07:42:08 -0700 Subject: [PATCH 26/26] docs(rfc): define catalog observation ownership --- rfcs/0017-command-catalog.md | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/rfcs/0017-command-catalog.md b/rfcs/0017-command-catalog.md index ffd3a8de..d56312bf 100644 --- a/rfcs/0017-command-catalog.md +++ b/rfcs/0017-command-catalog.md @@ -3,7 +3,7 @@ title: Command Catalog authors: - Gio created: 2026-07-04 -last_updated: 2026-07-23 +last_updated: 2026-07-28 status: draft issue: rfc_pr: https://github.com/openclaw/rfcs/pull/32 @@ -76,6 +76,8 @@ initial catalog contract or establish a token-savings claim. - Support exact inspection without scraping help text. - Give later documentation, diagnostics, prompt, and policy consumers one normalized input. +- Make command ownership, observation scope, and catalog-record lifetime + explicit for consumers that retain or compare results. ## Non-Goals @@ -195,12 +197,43 @@ commands are not stable compatibility promises. Plugin metadata remains optional but follows the same validation and unknown-preservation rules once emitted. +### Ownership and observation lifetime + +The registry or runtime that contributes a command remains the owner of its +name, semantics, registration lifetime, and execution behavior. The catalog +normalizes owner-supplied facts; it does not resolve registration conflicts, +extend a registration, or become the authority for invoking the command. + +A catalog record identifies a logical command observed from a labeled source. +It is not a capability token and does not prove that the same implementation is +still registered. Static descriptor records are bounded by the OpenClaw build +and configuration being inspected. Runtime and plugin records are bounded by +their current registration or plugin-activation lifetime. Node records are +bounded by the selected authenticated node observation. + +Each result is an observation snapshot with explicit collection scope and +source status. A missing or failed source means `unknown`, not that its commands +were removed. Drift consumers may compare stable record identity only between +snapshots whose relevant sources were collected under compatible scope; they +must preserve source status and must not infer revocation, authorization, or +availability from catalog absence alone. + +Visibility and prompt projections are views over the same records. Hiding or +excluding a record from one view does not disable the underlying command, and +including a record does not grant permission to execute it. Dispatch, +authorization, policy, and confirmation remain with their existing owners. + ## Acceptance Criteria - `commands list` and `commands inspect` execute no catalog record. - Omitted effect metadata remains omitted or explicitly unknown in JSON, Markdown, evidence, and prompt inputs. - Output reports whether runtime, plugin, and node sources were collected. +- Catalog records preserve owner provenance and their source observation scope; + they are never accepted as execution capabilities or current-availability + guarantees. +- Incomplete or failed source collection remains unknown, and drift comparison + does not interpret catalog absence as removal or revocation. - Hidden descriptors do not enter public list or generated-documentation views. - Requested plugin collection executes only enabled, trusted modules in the documented restricted mode and fails on incomplete error-level collection.