Versioning
Versioning
Section titled “Versioning”Protocol versioning and per-function versioning
Overview
Section titled “Overview”Forrst has two independent versioning systems, both using Semantic Versioning:
| Type | Scope | Changes |
|---|---|---|
| Protocol version | Envelope structure, error format, core semantics | Rare, coordinated |
| Function version | Business logic, arguments, return shape | Per-team, independent |
All versions in Forrst MUST use semantic versioning format: <major>.<minor>.<patch>[-<prerelease>] (e.g., "1.0.0", "2.1.0", "3.0.0-beta.1").
Protocol Versioning
Section titled “Protocol Versioning”Format
Section titled “Format”The protocol field specifies the Forrst protocol version using Semantic Versioning:
<major>.<minor>.<patch>Examples:
0.1.0— Draft/experimental1.0.0— First stable release1.2.0— Minor additions2.0.0— Breaking changes
Semantics
Section titled “Semantics”Major version — Breaking changes:
- Removing or renaming required fields
- Changing field types
- Altering error semantics
- Modifying core behavior
Minor version — Backwards-compatible additions:
- New optional fields
- New error codes
- New optional features
Patch version — Backwards-compatible fixes:
- Clarifications to specification text
- Documentation corrections
- No behavioral changes
Compatibility Rules
Section titled “Compatibility Rules”Servers MUST:
- Reject requests with unsupported major versions
- Accept requests with supported major version, any minor version
- Return
INVALID_PROTOCOL_VERSIONfor unsupported versions
Clients SHOULD:
- Send the protocol version they were built for
- Handle responses from any minor version of the same major
Example
Section titled “Example”// Request with unsupported version{ "protocol": { "name": "forrst", "version": "99.0.0" }, "id": "req_123", "call": { ... }}
// Response{ "protocol": { "name": "forrst", "version": "0.1.0" }, "id": "req_123", "result": null, "errors": [{ "code": "INVALID_PROTOCOL_VERSION", "message": "Unsupported protocol version: 99.0.0", "details": { "requested": "99.0.0", "supported": ["0.1.0"] } }]}Function Versioning
Section titled “Function Versioning”Philosophy
Section titled “Philosophy”Each function is versioned independently. This differs from REST’s monolithic API versioning:
REST (monolithic):
/api/v1/orders ← Forced to v1 because users changed/api/v1/users ← The actual change/api/v1/products ← Unchanged, but still "v1"Forrst (per-function):
orders.create@1.0.0 ← Untouchedusers.get@2.0.0 ← Evolved independentlyproducts.list@1.0.0 ← UntouchedBenefits
Section titled “Benefits”- Teams evolve functions without coordinating releases
- Consumers upgrade function-by-function
- No version sprawl where everything is “v7” but 90% is unchanged
- Deprecation is surgical: sunset
orders.create@1.0.0, not “all of v1”
Format
Section titled “Format”The version field in the call object specifies function version:
{ "call": { "function": "orders.create", "version": "2.0.0", "arguments": { ... } }}Type: String. MUST use Semantic Versioning: "1.0.0", "2.0.0", "3.0.0-beta.1"
Prerelease Versions
Section titled “Prerelease Versions”Function versions support semver prerelease identifiers to indicate stability:
3.0.0-alpha.1 ← Alpha release3.0.0-alpha.2 ← Second alpha3.0.0-beta.1 ← Beta release3.0.0-beta.2 ← Second beta3.0.0-rc.1 ← Release candidate3.0.0 ← Stable release (no prerelease tag)Stability is derived from the prerelease identifier:
| Prerelease Pattern | Stability | Description |
|---|---|---|
| (none) | stable | Production-ready, fully supported |
-alpha.* | alpha | Early development, breaking changes expected |
-beta.* | beta | Feature-complete, may have bugs |
-rc.* | rc | Release candidate, final testing |
Precedence: Versions are ordered per semver rules. Prerelease versions have lower precedence than stable:
1.0.0-alpha.1 < 1.0.0-beta.1 < 1.0.0-rc.1 < 1.0.0 < 1.0.1Example request for prerelease:
{ "call": { "function": "orders.create", "version": "3.0.0-beta.2", "arguments": { ... } }}Default Version Behavior
Section titled “Default Version Behavior”When a request omits the version field, servers SHOULD route to the latest stable version:
{ "call": { "function": "orders.create", "arguments": { ... } }}Resolution rules:
- Find all versions without prerelease identifiers (stable versions)
- Select the highest stable version number
- If no stable versions exist, return
VERSION_NOT_FOUND
Example: If a function has versions 1.0.0 (deprecated), 2.0.0, and 3.0.0-beta.1:
- Omitting version routes to
2.0.0(latest stable) - Explicitly requesting
3.0.0-beta.1routes to the beta
Recommendations:
- Clients SHOULD specify explicit versions in production code for predictability
- Servers SHOULD support version omission for exploration and development
- Version discovery: Use
urn:cline:forrst:fn:describeto find available versions and their status
// Discover versions before calling{ "call": { "function": "urn:cline:forrst:fn:describe", "version": "1.0.0", "arguments": { "function": "orders.create" } }}When to Increment
Section titled “When to Increment”Implementations MUST increment function version for:
- Removing or renaming arguments
- Changing argument types
- Changing return value structure
- Altering function behavior
Implementations SHOULD NOT increment for:
- Adding optional arguments with defaults
- Adding fields to return value
- Bug fixes that don’t change the contract
Maintaining Multiple Versions
Section titled “Maintaining Multiple Versions”Servers MAY support multiple versions simultaneously:
orders.create@1.0.0 ← Legacy, deprecatedorders.create@2.0.0 ← Current, recommended (latest stable)orders.create@3.0.0-beta.1 ← Beta testingorders.create@3.0.0-beta.2 ← Latest betaDeprecation
Section titled “Deprecation”To deprecate a function version:
- Document deprecation with timeline
- MAY return warning in
meta:{"meta": {"deprecated": {"reason": "Use version 2.0.0","sunset": "2025-06-01"}}} - Eventually return
VERSION_NOT_FOUND
Unknown Version
Section titled “Unknown Version”When a client requests an unknown version:
{ "protocol": { "name": "forrst", "version": "0.1.0" }, "id": "req_123", "result": null, "errors": [{ "code": "VERSION_NOT_FOUND", "message": "Version 5.0.0 not found for function orders.create", "details": { "function": "orders.create", "requested_version": "5.0.0", "available_versions": ["1.0.0", "2.0.0", "3.0.0-beta.1", "3.0.0-beta.2"] } }]}Version Discovery
Section titled “Version Discovery”Clients MAY discover available versions using system functions:
// Request{ "protocol": { "name": "forrst", "version": "0.1.0" }, "id": "req_discover", "call": { "function": "urn:cline:forrst:fn:describe", "version": "1.0.0", "arguments": { "function": "orders.create" } }}
// Response{ "protocol": { "name": "forrst", "version": "0.1.0" }, "id": "req_discover", "result": { "function": "orders.create", "versions": [ { "version": "1.0.0", "stability": "stable", "deprecated": { "reason": "Use version 2.0.0", "sunset": "2025-06-01" } }, { "version": "2.0.0", "stability": "stable" }, { "version": "3.0.0-beta.1", "stability": "beta" }, { "version": "3.0.0-beta.2", "stability": "beta" } ] }}See System Functions for details.
Examples
Section titled “Examples”Version 1 Request
Section titled “Version 1 Request”{ "protocol": { "name": "forrst", "version": "0.1.0" }, "id": "req_v1", "call": { "function": "users.get", "version": "1.0.0", "arguments": { "user_id": 42 } }}Version 1 Response
Section titled “Version 1 Response”{ "protocol": { "name": "forrst", "version": "0.1.0" }, "id": "req_v1", "result": { "id": 42, "name": "Alice", "email": "alice@example.com" }}Version 2 Request (Different Arguments)
Section titled “Version 2 Request (Different Arguments)”{ "protocol": { "name": "forrst", "version": "0.1.0" }, "id": "req_v2", "call": { "function": "users.get", "version": "2.0.0", "arguments": { "identifier": { "type": "id", "value": 42 } } }}Version 2 Response (Different Structure)
Section titled “Version 2 Response (Different Structure)”{ "protocol": { "name": "forrst", "version": "0.1.0" }, "id": "req_v2", "result": { "user": { "id": 42, "profile": { "name": "Alice", "email": "alice@example.com" }, "metadata": { "created_at": "2024-01-01T00:00:00Z" } } }}