Repository navigation
bug(docs): supervisor middleware docs no longer name the base capability that Describe must return #4378
Description
User Story
I use OpenShell 0.1.2 with a supervisor middleware I wrote in Python (grpcio, stubs generated from proto/supervisor_middleware.proto at v0.1.2). To get past Describe I needed the protocol version and the base capability that MiddlewareManifest.extension must declare, and I could not find the capability name in the docs or the proto.
Problem Statement
#3352 (closing #3057) added docs/extensibility/extension-negotiation.mdx, with a table of each family's base capability, and a sentence in the supervisor middleware guide telling authors to "return protocol 1.0 plus openshell.supervisor-middleware.contract". At v0.1.2 and on main today, neither is there:
docs/extensibility/overview.mdx(Protocol Negotiation) describesPeerMetadatain general terms but gives no values.docs/upgrade/0-1-0.mdxsays to "use protocol1.0, and advertise their family base capability", but never names the capability, and its link points to the overview section above.proto/supervisor_middleware.protomarksMiddlewareManifest.extension"Required for negotiation" with no values.
The capability string openshell.supervisor-middleware.contract appears only in openshell_core::extension_protocol, which is where I found it. The Rust reference middleware gets it from a helper (extension_metadata), so a Rust author never sees it either.
Question for maintainers: going by the commit history, #3636 replaced the middleware guide's sentence with a link to the negotiation page, and #3705 then removed that page. Was the base capability table meant to move somewhere else as part of those changes?
Impact / Why This Matters
Any middleware author outside Rust has to read the Rust source to complete Describe. #3057 listed "Extension author documentation and migration notes include the new handshake" as an acceptance criterion, and the same gap affects authors of compute drivers, credential drivers and gateway interceptors: none of the four base capability names appears in the v0.1.2 docs or protos.
Acceptance Criteria
- The docs name the base capability for each extension family, for example by bringing back the table from feat(extensions)!: normalize protocol negotiation #3352 in the overview's Protocol Negotiation section or on the supervisor middleware page, ideally with a small example manifest.
proto/supervisor_middleware.protonames the expected values next toMiddlewareManifest.extension.- When negotiation fails, the gateway error includes the expected protocol version and capability.
Reproduction Steps
- Open the v0.1.2 supervisor middleware docs, the extensibility overview, the 0.1.0 upgrade guide and
proto/supervisor_middleware.proto. - Look for the capability string a middleware must declare in
MiddlewareManifest.extension. - It is not named in any of them. It appears in
crates/openshell-core/src/extension_protocol.rs.
Environment
- OpenShell 0.1.2, Homebrew install on macOS 26.6.2 (Apple Silicon), Docker driver
- Middleware: Python 3.13, grpcio, stubs generated at tag v0.1.2
Logs
None. A working Python middleware against 0.1.2 is described in entries 22 and 33 of https://github.com/SoniaMehta14/paved-gate/blob/main/docs/openshell/FRICTION_LOG.md
Activity
docs(extensibility): name extension family base capabilities
johntmyers commentedon Oct 12, 2026
@SoniaMehta14 does PR #4405 address your needs?
SoniaMehta14 commentedon Oct 12, 2026
@johntmyers yes, thanks. #4405 covers everything I asked for: the base capability table and example manifest in the Protocol Negotiation section, the values next to each
extensionfield in the protos, and the expected protocol and capability in the missing metadata and missing version errors. The missing capability error already names the capability, so that case was covered.The example matches what my Python middleware returns from
Describeagainst 0.1.2. One optional addition: a sentence sayingrequired_capabilitiescan stay empty. The Rustextension_metadatahelper also lists the base capability there, which is why I copied it, and from the docs alone it was not clear whether that was needed.