* feat(#1684): add negotiated host-integration interface module ADR-1239 Phase A: a pure, additive, no-I/O module exposing PROTOCOL_VERSION, the 8-axis HOST_INTEGRATION_AXES closed vocabulary, the UNDOCUMENTED fail-closed sentinel, negotiateHostCapabilities (effective subset of host-declared and engine-known), a typed degradation ladder, and host-capability profiles. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(#1684): validate and document host-integration axes (16 runtimes) Extend validateRuntimeBody to validate the 8 hostIntegration axes (closed enums + undocumented sentinel + dispatch struct + reserved-key guards) and the widened runtime vocabulary; author a documentation-sourced hostIntegration block in all 16 runtime descriptors; regenerate the registry. Every per-CLI value is documented (cited) or the explicit undocumented sentinel. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(#1684): add host-integration capability matrix and adr amendment New per-CLI, per-axis citation reference (value/source/evidence for all 16 CLIs); ADR-1239 Phase-A-implemented amendment; CONTEXT.md glossary seam entry. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(#1684): harden dispatch negotiation edge cases Code-review hardening: treat NaN/Infinity maxDepth as missing (fail-closed, +warning); reset nested/background when namedDispatch collapses to false (struct consistency); SAFE_DEFAULTS dispatch floor to read-only; warn on non-finite protocolVersion; symmetric undocumented warnings for dispatch fields. Pure module — no consumers; behaviour fail-closed throughout. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(#1684): register host-integration.cjs in lint-ignore and inventory New tsc-generated bin/lib artifact: add to the eslint ignore list (ADR-457 — lint the .cts source), regenerate docs/INVENTORY-MANIFEST.json, and add the docs/INVENTORY.md CLI-modules row. Fixes the 3 gsd-test failures (551-eslint-bin-lib-coverage x2 + inventory-manifest-sync). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(#1684): add changeset fragment for host-integration interface Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(#1684): add how-to for sourcing a host's integration axes Diataxis how-to guide for adding/updating a host's runtime.hostIntegration axes from authoritative docs, the undocumented-sentinel rule, validation, and extending the closed vocabulary. Completes the Step-5 doc quadrants (reference + explanation + how-to). Indexed in docs/README.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
112 lines
5.8 KiB
Markdown
112 lines
5.8 KiB
Markdown
# How to add or update a host's integration capabilities
|
|
|
|
This guide is for GSD maintainers adding a new host CLI, or updating an existing host's
|
|
host-integration axes (ADR-1239 Phase A). It covers the **documentation-sourcing rule**, the
|
|
eight `runtime.hostIntegration` axes, the `undocumented` sentinel, and how to validate.
|
|
|
|
The governing rule for this whole process: **every axis value must come from the host's own
|
|
authoritative documentation. Never infer, guess, or assume.** Where the docs do not state an axis,
|
|
record the explicit `undocumented` sentinel — not a plausible default. The reference matrix
|
|
(`docs/reference/host-integration-capability-matrix.md`) is the source of truth, and every value in
|
|
it carries a citation and an evidence quote.
|
|
|
|
---
|
|
|
|
## 1. Find the host's authoritative documentation
|
|
|
|
In order of preference:
|
|
|
|
1. **Context7** — `resolve-library-id` for the host, then `query-docs` for "plugins / subagents / hooks / commands / MCP / model API".
|
|
2. **Official dev docs / source repo** — the host's documentation site or GitHub repo (plugin API, agents, hooks, MCP, command authoring).
|
|
|
|
Capture the exact source (Context7 library id + query, or the doc URL) and a short verbatim quote
|
|
for each value you determine. You will paste these into the matrix in step 4.
|
|
|
|
## 2. Determine each of the eight axes from the docs
|
|
|
|
Read the docs and map them to the closed vocabulary. Do not pick a value unless a source states it.
|
|
|
|
| Axis | What to look for in the docs |
|
|
|---|---|
|
|
| `embeddingMode` | An in-process programmatic plugin/extension API (`imperative`) vs. configuration files only (`declarative`). |
|
|
| `commandSurface` | How custom commands are authored/invoked: `slash-file` (.md), `slash-toml`, `slash-programmatic`, `palette`, `prose-only`. |
|
|
| `dispatch` | Sub-agent delegation: `namedDispatch`, `nested`, `maxDepth` (int; `-1` = documented-unbounded), `background`, `subagentToolkit` (`full`/`read-only`). |
|
|
| `modelMode` | A programmatic model request/provider API (`active`) vs. instruction/per-agent-field only (`passive`). |
|
|
| `hookBus` | The host fires lifecycle events a plugin subscribes to (`host`), an extension host owns the bus (`engine`), or no bus (`none`). **Independent of `hooksSurface`** — e.g. opencode has `hooksSurface: none` but `hookBus: host`. |
|
|
| `stateIO` | `filesystem`, `sandboxed-storage` (web IDE, no arbitrary FS), or `session-log-append`. |
|
|
| `transport` | `mcp` (native MCP support) vs. `native-extension` (MCP needs a community extension). |
|
|
| `runtime` | The plugin/extension runtime: `node`, `bun`, `sandboxed-web`, `python`, `go`, `rust`, `electron`, `other`. |
|
|
|
|
## 3. Write the `runtime.hostIntegration` block
|
|
|
|
In `capabilities/<id>/capability.json`, inside the `runtime` object, add (or edit) the block. Use a
|
|
documented closed-vocabulary value, or the literal string `"undocumented"` for any axis the docs do
|
|
not state:
|
|
|
|
```json
|
|
"hostIntegration": {
|
|
"embeddingMode": "declarative",
|
|
"commandSurface": "slash-file",
|
|
"dispatch": { "namedDispatch": true, "nested": false, "maxDepth": 1, "background": false, "subagentToolkit": "undocumented" },
|
|
"modelMode": "passive",
|
|
"hookBus": "host",
|
|
"stateIO": "filesystem",
|
|
"transport": "mcp",
|
|
"runtime": "node"
|
|
}
|
|
```
|
|
|
|
**When to use `undocumented`:** only when you searched and the host's docs genuinely do not state the
|
|
axis. It validates, but `negotiateHostCapabilities` **fail-closes** on it (degrades to the most
|
|
restrictive known value) — so it is always safe and never a silent capability claim. A dispatch
|
|
boolean or `maxDepth` may also be `"undocumented"`.
|
|
|
|
**Do not conflate the orthogonal axes:** `commandStyle` (GSD's emission style) is *not*
|
|
`commandSurface` (the host's surface type); the `hookEvents` dialect is *not* `hookBus` (bus
|
|
ownership); `runtimeCompat` (which features run on a host) is independent of these runtime→engine
|
|
axes.
|
|
|
|
## 4. Record the citations in the reference matrix
|
|
|
|
Add (or update) the host's section in `docs/reference/host-integration-capability-matrix.md` with a
|
|
row per axis: `Axis | Value | Source | Evidence`. For an `undocumented` value, put the search trail
|
|
in the Source column. This file is the deployment source of truth — a value without a citation here
|
|
is not allowed.
|
|
|
|
## 5. Validate
|
|
|
|
```bash
|
|
npm run build:lib
|
|
npm run gen:capability-registry # validateRuntimeBody runs on every descriptor
|
|
```
|
|
|
|
`gen:capability-registry` must succeed with zero errors. The validator
|
|
(`gsd-core/bin/lib/capability-validator.cjs`) rejects out-of-vocabulary values, malformed dispatch
|
|
structs, and reserved keys (`__proto__`/`constructor`/`prototype`).
|
|
|
|
Then run the host-integration tests and the full cross-platform suite:
|
|
|
|
```bash
|
|
node --test tests/host-integration-descriptors.test.cjs # asserts every descriptor validates + profiles
|
|
gsd-test-both # Mac + Linux Docker (run before any PR)
|
|
```
|
|
|
|
## 6. If you need a vocabulary value that does not exist yet
|
|
|
|
The vocabulary is intentionally **closed** (ADR-857 Decision 8): a genuinely new host shape requires
|
|
a first-party primitive, reviewed. To add one (e.g. a new `runtime` kind):
|
|
|
|
1. Add the value to the relevant axis in `HOST_INTEGRATION_AXES` in `src/host-integration.cts`.
|
|
2. Add the same value to the matching `VALID_*` set in `capability-validator.cjs`.
|
|
|
|
The parity guard (`tests/host-integration-validator-parity.test.cjs`) fails if these two drift, so
|
|
they must be updated together. Document the new value's meaning in the matrix legend.
|
|
|
|
---
|
|
|
|
## Related
|
|
|
|
- Reference: [`docs/reference/host-integration-capability-matrix.md`](../reference/host-integration-capability-matrix.md) — the per-CLI sourced values.
|
|
- ADR: [`docs/adr/1239-gsd-embeddable-orchestration-engine.md`](../adr/1239-gsd-embeddable-orchestration-engine.md) — why the interface exists and the Phase A amendment.
|
|
- The closed-vocabulary runtime descriptor it extends: [ADR-1016](../adr/1016-runtime-capability-descriptor.md).
|