|
| 1 | +--- |
| 2 | +authors: |
| 3 | + - "@drew" |
| 4 | +state: review |
| 5 | +links: |
| 6 | + - https://github.com/NVIDIA/OpenShell/pull/2148 |
| 7 | + - https://github.com/NVIDIA/OpenShell/pull/2695 |
| 8 | +--- |
| 9 | + |
| 10 | +# RFC 0014 - Alpha Exit Criteria and Stable Release Policy |
| 11 | + |
| 12 | +## Summary |
| 13 | + |
| 14 | +The goal of this RFC is to define OpenShell's exit from alpha and establish a |
| 15 | +predictable release cycle for production users and ecosystem developers. |
| 16 | + |
| 17 | +We propose |
| 18 | + |
| 19 | +- Development releases for every commit to `main`, nightly pre-releases, and |
| 20 | + qualified stable releases every Tuesday. |
| 21 | +- Stable and Experimental API maturity, compatibility, and versioning |
| 22 | + rules, and maintenance for the latest and N-1 minor release lines. |
| 23 | +- A release qualification pipeline covering conformance, upgrades, |
| 24 | + API changes, and security reviews across the supported release matrix. |
| 25 | + |
| 26 | +## Motivation |
| 27 | + |
| 28 | +The goal is to exit alpha without slowing OpenShell's development. Releases |
| 29 | +should remain frequent and automated, and Experimental APIs should be able to |
| 30 | +evolve quickly enough to keep pace with the ecosystem. At the same time, users |
| 31 | +need Stable interfaces they can confidently build on. |
| 32 | + |
| 33 | +Starting with `0.1.0`, OpenShell provides both: a defined compatibility contract |
| 34 | +for Stable interfaces and room to evolve Experimental APIs and features. |
| 35 | +Releases are suitable for production use within the published support matrix |
| 36 | +only after passing conformance, upgrade, compatibility, artifact, and security |
| 37 | +checks. |
| 38 | + |
| 39 | +## Proposal |
| 40 | + |
| 41 | +### Release cadence |
| 42 | + |
| 43 | +Starting with `0.1.0`, OpenShell publishes stable tagged releases intended for production use within |
| 44 | +the published support matrix. Stable releases occur every Tuesday and increment |
| 45 | +the patch version by default, for example `0.1.1` followed by `0.1.2`. A release |
| 46 | +may instead increment the minor version when it introduces notable new features |
| 47 | +or documented breaking changes. A stable tag is published only when there are |
| 48 | +changes and every blocking qualification suite passes. |
| 49 | + |
| 50 | +OpenShell publishes a development release for every commit to `main`. Each |
| 51 | +development release identifies its source commit and artifact manifest, and the |
| 52 | +floating `dev` alias points to the newest one. Development releases enable all |
| 53 | +development compilation flags and features. They give feature authors, early |
| 54 | +adopters, and integration owners a way to consume upcoming OpenShell changes |
| 55 | +between stable releases. This also allows development of a large feature to |
| 56 | +span multiple weeks behind a compile-time feature flag without including the |
| 57 | +unfinished feature in the stable release track. Development releases have |
| 58 | +passed normal CI, but have not passed release qualification and are not |
| 59 | +intended for production use. |
| 60 | + |
| 61 | +OpenShell builds a pre-release nightly for the next expected stable release |
| 62 | +when `main` has changed and normal CI passes. After `0.1.1`, pre-releases are |
| 63 | +numbered `0.1.2-pre.1`, `0.1.2-pre.2`, and so on. Features may land between |
| 64 | +pre-releases. The first pre-release locks the version for that weekly release |
| 65 | +train. Once a patch train starts, breaking changes that require a minor release |
| 66 | +are staged for the following week; the train never switches from patch to minor. |
| 67 | + |
| 68 | +Pre-releases give the automated release qualification and QA systems an |
| 69 | +immutable artifact set to evaluate. They are also available to maintainers and |
| 70 | +integration owners who need to validate the prospective stable release. A |
| 71 | +pre-release uses the same release feature set as stable and may still fail |
| 72 | +qualification; it is not intended for production use. Building one nightly |
| 73 | +allows failures to be fixed and reevaluated before Tuesday. |
| 74 | + |
| 75 | +| Release | Intended users | Contents and expectations | |
| 76 | +| --- | --- | --- | |
| 77 | +| Development | Feature authors, early adopters, and integration owners testing upcoming functionality | Published for every commit to `main`; enables development features; passes normal CI but not release qualification | |
| 78 | +| Pre-release | Automated qualification, maintainers, and integration owners validating the next stable release | Built nightly from eligible `main`; uses the stable feature set; immutable but not yet qualified for production | |
| 79 | +| Stable | Production users and downstream integrations that require the published compatibility and support contract | Published Tuesday from a pre-release that passed every blocking qualification suite | |
| 80 | + |
| 81 | +### Project version and compatibility contract |
| 82 | + |
| 83 | +Version `0.1.0` begins OpenShell's supported compatibility contract. For |
| 84 | +the `0.x` series: |
| 85 | + |
| 86 | +- Patch releases may contain bug fixes and additive, backward-compatible |
| 87 | + functionality. They do not intentionally break a stable interface. |
| 88 | +- Minor releases may represent notable new features even when they remain |
| 89 | + backward-compatible. They may also contain documented breaking changes to |
| 90 | + stable interfaces, for example `0.1.x` to `0.2.0`. |
| 91 | + |
| 92 | +The [release version selection supplement](release-version-selection.md) |
| 93 | +defines how Conventional Commits select the next patch or minor release |
| 94 | +pre-release. |
| 95 | + |
| 96 | +### API and feature maturity |
| 97 | + |
| 98 | +Public APIs are Stable by default. APIs that are expected to change frequently |
| 99 | +must be explicitly designated Experimental. Protobuf packages encode the |
| 100 | +designation in their version name. SDKs use language-appropriate package, |
| 101 | +module, namespace, or symbol naming to expose the same designation. |
| 102 | + |
| 103 | +| Maturity | Protobuf naming | SDK naming | Compatibility | |
| 104 | +| --- | --- | --- | --- | |
| 105 | +| Stable | `v1` or `v2` | Default Stable package, module, namespace, or symbol | Backward-compatible across patch releases; may change in a minor release with notice and migration guidance | |
| 106 | +| Experimental | `v1experimental` | Language-specific Experimental package, module, namespace, or symbol | May change or be removed in a patch release without notice | |
| 107 | + |
| 108 | +Every API and feature is Stable or Experimental, regardless of whether it |
| 109 | +appears in stable, pre-release, or development artifacts. Each SDK must |
| 110 | +document its language-specific naming convention, and Experimental interfaces |
| 111 | +must not appear to be Stable. |
| 112 | + |
| 113 | +Experimental APIs are intended for rapid iteration and may change in place |
| 114 | +without a compatibility guarantee. Graduation adds a Stable `v1` package |
| 115 | +instead of renaming the Experimental package in place. |
| 116 | + |
| 117 | +Unreleased features use named compile-time flags such as `unstable-<feature>`, |
| 118 | +collected under a `dev` compilation flag. Development releases enable them; stable |
| 119 | +releases and pre-releases exclude them from service binaries, the CLI, |
| 120 | +configuration, and documentation. For now, SDK distributions may include their |
| 121 | +generated types and client methods when the SDK naming convention communicates |
| 122 | +their maturity. |
| 123 | + |
| 124 | +### Breaking changes and API versioning |
| 125 | + |
| 126 | +A breaking change to a Stable API or other stable OpenShell surface requires a |
| 127 | +minor release with notice and migration guidance. This applies to Protobuf, |
| 128 | +SDK, CLI, configuration, policy, Helm, and state interfaces. A breaking |
| 129 | +Experimental API change may ship in a patch release without notice when it does |
| 130 | +not break a Stable interface. |
| 131 | + |
| 132 | +Breaking-change detection runs during code review and again during pre-release |
| 133 | +qualification. Stable protobuf packages use Buf's `FILE` rules |
| 134 | +against the latest stable baseline and any additional supported baseline needed |
| 135 | +for the N-1 maintenance promise. Language-specific API checks or agent review |
| 136 | +skills cover the public SDKs. |
| 137 | + |
| 138 | +The following examples illustrate how these rules affect a pre-release: |
| 139 | + |
| 140 | +| Example | Concrete change | Release treatment | |
| 141 | +| --- | --- | --- | |
| 142 | +| Breaking Stable Protobuf contract | `string policy = 7` to `PolicyReference policy = 7` | Blocks a patch release and requires a minor OpenShell release. | |
| 143 | +| Breaking Experimental Python SDK method | `create_sandbox(timeout=30)` to `create_sandbox(deadline=...)` | May ship in a patch release without notice. | |
| 144 | +| Breaking stable policy document | `endpoints:` to `destinations:` | Blocks a patch release unless both fields remain supported. | |
| 145 | +| Breaking stable CLI contract | `--policy policy.yaml` to `--policy-file policy.yaml` | Requires retaining the old flag as an alias or shipping a minor release. | |
| 146 | + |
| 147 | +### Pre-release qualification and stable publication |
| 148 | + |
| 149 | +The release system separates pre-release creation, qualification, and stable |
| 150 | +publication: |
| 151 | + |
| 152 | +```mermaid |
| 153 | +flowchart LR |
| 154 | + A["Commit to main"] --> B["Dev release<br/>dev features enabled"] |
| 155 | + A --> C["Normal CI passes"] |
| 156 | + C --> D["Tag and build nightly pre-release<br/>release feature set"] |
| 157 | + D --> E["Pre-release qualification"] |
| 158 | + E -->|"pass"| F["Eligible Tuesday pre-release"] |
| 159 | + E -->|"fail"| G["No stable release"] |
| 160 | + F --> H["Publish stable artifacts"] |
| 161 | + H --> I["Final artifact checks"] |
| 162 | + I -->|"pass"| J["Create tag and publish"] |
| 163 | + I -->|"fail"| G |
| 164 | +``` |
| 165 | + |
| 166 | +Every pre-release is tagged before qualification and produces a manifest with |
| 167 | +its version, source commit, build inputs, artifact digests, SBOM, provenance, |
| 168 | +and qualification results. Qualification exercises those artifacts rather than |
| 169 | +a substitute source build. Pre-releases are stored in artifact storage instead |
| 170 | +of published as GitHub Releases, following the |
| 171 | +[Bazel rolling release model](https://bazel.build/release/rolling). Any change |
| 172 | +creates a new pre-release. |
| 173 | + |
| 174 | +Release qualification consists of four suites defined in the |
| 175 | +[release qualification supplement](release-qualification.md): |
| 176 | + |
| 177 | +- **Conformance** runs across supported driver and gateway configurations. It |
| 178 | + verifies core sandbox behavior, policy enforcement, and extension contracts. |
| 179 | +- **Upgrade** runs once per supported installation package and verifies its |
| 180 | + upgrade path, state migration, post-upgrade health, and rollback where |
| 181 | + promised. |
| 182 | +- **Breaking API change review** runs once per pre-release and compares stable |
| 183 | + protobuf and SDK interfaces with every applicable compatibility baseline. |
| 184 | +- **Security review** runs once per pre-release and verifies security scan |
| 185 | + results, reviews changes to security-sensitive boundaries, and confirms that |
| 186 | + every finding has the required disposition. |
| 187 | + |
| 188 | +The initial release targets are defined in the [build matrix](build-matrix.md), |
| 189 | +and blocking coverage is defined in the |
| 190 | +[release qualification supplement](release-qualification.md). |
| 191 | + |
| 192 | +The weekly release tags the newest eligible pre-release commit with the next |
| 193 | +stable version and publishes the stable artifacts. |
| 194 | + |
| 195 | +### Maintenance and backports |
| 196 | + |
| 197 | +OpenShell maintains two release lines: the latest minor and N-1. Support |
| 198 | +applies to the newest patch on each line. Users on an older patch update to the |
| 199 | +new maintenance patch rather than receiving a separate fix for every historical |
| 200 | +patch. |
| 201 | + |
| 202 | +Maintenance releases contain critical reliability fixes and security fixes. |
| 203 | +They do not backport features. A fix is developed on the appropriate primary |
| 204 | +branch and backported to a `release/<major>.<minor>` branch when the older line |
| 205 | +is affected. Each backport passes the compatibility, regression, packaging, |
| 206 | +and supported upgrade qualification appropriate to that line. |
| 207 | + |
| 208 | +For example, if `0.3.1` is current and a vulnerability also affects the 0.2 |
| 209 | +line, OpenShell publishes the next available `0.2.x` patch from the maintained |
| 210 | +0.2 branch. A security release may occur immediately rather than waiting for |
| 211 | +the next Tuesday release. |
| 212 | + |
| 213 | +## Implementation plan |
| 214 | + |
| 215 | +1. **Keep per-commit dev releases and build 0.1.0 pre-releases nightly.** Build |
| 216 | + every commit to `main` with all development features, and publish sequential |
| 217 | + `0.1.0-pre.N` artifacts with the release feature set leading to 0.1.0. |
| 218 | +2. **Make the necessary breaking API changes.** Use the pre-0.1.0 window to |
| 219 | + finalize Stable interfaces, move evolving APIs to Experimental packages, |
| 220 | + and establish the compatibility baseline. |
| 221 | +3. **Build qualification tests and release machinery.** Automate compatibility |
| 222 | + detection, conformance, upgrade, breaking API change review, security |
| 223 | + qualification, artifact validation, and release publication gates. |
| 224 | +4. **Release 0.1.0.** Select a qualified pre-release, publish the stable |
| 225 | + artifacts and support guidance, and begin the weekly release cadence. |
0 commit comments