mirror of
https://github.com/NVIDIA/OpenShell.git
synced 2026-10-17 05:31:16 +08:00
Remove architecture/. It was a constant source of merge conflicts, became an effectively append-only log of the project, and was of dubious value. Design records live in rfc/, crate details in crate READMEs, and user documentation in docs/. Move the git-ignored plans directory from architecture/plans to plans/, keeping the old .gitignore entry. Remove the arch-doc-writer agents and update AGENTS.md, CONTRIBUTING.md, skills, the feature request template, and links in proto/, rfc/, and examples/ that pointed into architecture/. Signed-off-by: Kris Hicks <khicks@nvidia.com>
88 lines
3.7 KiB
Markdown
88 lines
3.7 KiB
Markdown
<!--
|
|
SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
SPDX-License-Identifier: Apache-2.0
|
|
-->
|
|
|
|
# Protobuf API conventions
|
|
|
|
This directory defines OpenShell's gRPC contracts. These conventions are the
|
|
source of truth for public protobuf API design. Apply them to new APIs and when
|
|
changing existing APIs; generated SDK naming follows from these definitions.
|
|
|
|
## Entity references
|
|
|
|
- Use `name` for the primary resource targeted by an RPC.
|
|
- Use the resource's role for a related resource reference, such as `sandbox`,
|
|
`provider`, `service`, or `rule`.
|
|
- Do not append `_name` to a canonical entity reference. Its value is already
|
|
the canonical name. Descriptive values, local map keys, implementation
|
|
labels, and configured registration names that are not entity references may
|
|
retain the suffix. Examples include `display_name`, `file_name`,
|
|
`driver_name`, `runtime_class_name`, `rule_name`, and `middleware_name`.
|
|
- Public callers reference entities by canonical name. Keep immutable IDs at
|
|
authentication, persistence, compute-driver, and other internal boundaries.
|
|
|
|
For example:
|
|
|
|
```proto
|
|
message GetSandboxRequest {
|
|
openshell.datamodel.v1.WorkspaceSelector workspace_scope = 2;
|
|
string name = 1;
|
|
}
|
|
|
|
message ExposeServiceRequest {
|
|
openshell.datamodel.v1.WorkspaceSelector workspace_scope = 5;
|
|
string sandbox = 1;
|
|
string name = 2;
|
|
}
|
|
```
|
|
|
|
`GetSandboxRequest.name` identifies the RPC's primary resource.
|
|
`ExposeServiceRequest.sandbox` identifies a related sandbox while `name`
|
|
identifies the service being exposed.
|
|
|
|
## Workspace scope
|
|
|
|
- Public workspace-scoped requests declare `workspace_scope` before every
|
|
other field. Existing wire field numbers do not need to follow declaration
|
|
order.
|
|
- Type `workspace_scope` as
|
|
`openshell.datamodel.v1.WorkspaceSelector`.
|
|
- Requests operating in one workspace require a non-empty canonical
|
|
`WorkspaceSelector.workspace`. The `default` workspace is an explicit name,
|
|
not an omitted-value fallback.
|
|
- Accept `WorkspaceSelector.all_workspaces` only on collection-list RPCs that
|
|
explicitly document and authorize cross-workspace access. The supported
|
|
public collections are sandboxes, sandbox templates, providers, and
|
|
services.
|
|
- Requests whose primary resource is a workspace use `name`, not
|
|
`workspace_scope`.
|
|
- Document every request that permits an omitted selector. Current exceptions
|
|
are platform provider-profile scope and authenticated sandbox bootstrap.
|
|
|
|
## Field and message design
|
|
|
|
- Prefer a dedicated request and response message for each RPC, including
|
|
requests that are currently empty.
|
|
- Use `google.protobuf.Timestamp` for absolute time and
|
|
`google.protobuf.Duration` for elapsed time.
|
|
- Use optional presence when omitted and explicitly empty values have different
|
|
meanings. Do not infer presence from a protobuf scalar's default value.
|
|
- Keep public request fields in semantic reading order. Field numbers preserve
|
|
wire identity and may therefore differ from declaration order.
|
|
- Document authorization-sensitive selector variants and omission semantics on
|
|
the containing request.
|
|
|
|
## Schema evolution
|
|
|
|
- Treat field numbers and fully qualified message names as durable wire
|
|
identities.
|
|
- When removing or renaming a field, reserve its old number and source name. Do
|
|
not reuse either for a different meaning.
|
|
- Review changes against both the public descriptor closure and durable stored
|
|
protobuf closure. The `public_and_durable_schema_inventories_are_complete`
|
|
test in `openshell-server` owns both inventories.
|
|
- Regenerate Rust, Python, Go, and TypeScript bindings after contract changes.
|
|
Run `mise run pre-commit`, the affected SDK checks, and relevant server tests
|
|
before submitting the change.
|