# Version Sets & Promotion

Version sets define which agent, state machine, and model preferences a service uses. They let you iterate safely, like Git branches, while keeping production stable.

* **Purpose**: pin exact versions for a service run (agent, state machine, LLM model preferences).
* **Analogy**: treat version sets like Git branches for your service configuration.
* Two special sets exist on every service:
  * `edge`: always points to the latest agent and state machine with no model preferences. Locked from updates; can't be deleted.
  * `release`: the default version set used when clients don't specify one. Can't be deleted, but can be updated to promote changes.

{% hint style="warning" %}
Guardrails

* `edge` cannot be updated or deleted.
* `release` cannot be deleted and is the default when no version set is specified.
* Custom version sets cannot be deleted if they're referenced by simulation unit tests.
  {% endhint %}

## What Each Special Set Means

* `edge` (locked default settings)
  * Always the latest agent and state machine, with no explicit LLM preferences.
  * Cannot be updated via the upsert API and cannot be deleted.
  * Use it for quick local validation or smoke checks, not for stable user exposure.
* `release` (default exposed to users)
  * Used by conversations and real-time APIs when `service_version_set_name` is not provided.
  * Cannot be deleted, but can be updated to promote a tested configuration to production.

## Creating and Updating Version Sets

* **Create/Update**: use the Service Version Set upsert API to create named sets (for example, `personal-alex`, `test`, `preview`). All sets except `edge` are updatable.
* **Delete**: allowed for custom sets, but not for `edge` or `release`. Deletion is blocked if a set is referenced by any simulation unit tests.
* **Permissions**:
  * Create: `Service:CreateVersionSet`
  * Update: `Service:UpdateVersionSet`
  * Delete: `Service:DeleteVersionSet`

## How Version Sets Are Used at Runtime

* Conversation APIs default to `release` if `service_version_set_name` is omitted.
* Simulation unit tests and test runs must explicitly specify the target version set.
* Services are created with both `edge` and `release` by default. `release` equals `edge` unless you specify otherwise at creation time.

## Recommended Workflow (Git-Branch Style)

1. **Personal branch**
   * Create a personal version set (for example, `personal-yourname`), pin agent and state machine versions, and set LLM preferences.
   * Iterate locally and validate via small, focused simulation unit tests.
2. **Merge into `test`**
   * Upsert the shared `test` version set with your candidate configuration.
   * Run your simulation unit test set on `test`. Fix regressions here.
3. **Promote to `preview`**
   * Copy the `test` configuration into `preview` (another named version set).
   * Run the full simulation suite on `preview` and conduct stakeholder UAT.
4. **Release**
   * If `preview` passes full sims and UAT, promote by updating `release` with the same configuration (upsert `release` to match `preview`).
   * Don't delete `release` or `edge`. Use them as stable anchors.

### Promotion Flow

{% @mermaid/diagram content="---
config:
gitGraph:
mainBranchName: 'release'
showCommitLabel: true
rotateCommitLabel: true
-----------------------

gitGraph
commit id: "Initial" tag: "v1.0.0"

```
%% First development cycle
branch personal-dev
commit id: "Agent v2"
commit id: "LLM: standard"
commit id: "State: v3"

checkout release
branch test
checkout personal-dev
commit id: "Agent v2"
checkout test
commit id: "Test passed ✓"

checkout release
branch preview
checkout test
commit id: "Test passed ✓"
checkout preview
commit id: "UAT ✓" type: HIGHLIGHT

checkout release
merge preview id: "Promote" tag: "v1.1.0" type: HIGHLIGHT

%% Second development cycle
checkout release
commit id: "Stable"
branch personal-dev-2
commit id: "Agent v3"

checkout release
branch edge
commit id: "Auto-latest" type: REVERSE tag: "🔒 Locked"" %}
```

## CLI Commands (`forge version-set`)

Agent Forge provides CLI commands to manage version sets directly from the terminal.

### List Version Sets

```bash
forge version-set list MyService -e production

# JSON output for scripting
forge version-set list MyService -e production --json
```

Shows all version sets for a service with their pinned versions and LLM preferences.

### Create/Update a Version Set

```bash
# Create with unpinned versions (dev only)
forge version-set upsert personal-alex -s MyService -e dogfood --apply

# Create with pinned versions (resolves current latest)
forge version-set upsert personal-alex -s MyService -e dogfood --latest --apply

# Create by copying from another version set
forge version-set upsert preview -s MyService -e production --copy-from test --apply

# Pin specific versions
forge version-set upsert preview -s MyService -e production -a 5 -g 3 --apply
```

{% hint style="info" %}
**Dry-run by default.** All mutating commands show what would change without `--apply`. Add `--apply` to execute.
{% endhint %}

#### Version Existence Validation

When pinning to specific versions using `-a` (agent) or `-g` (context graph) flags, the CLI validates that those versions actually exist before applying the change.

```bash
$ forge version-set upsert preview -s MyService -e production -a 999 -g 888 --apply

Error: Agent version 999 does not exist. Use 'forge asset agent version-list' to see available versions.
Error: Context graph version 888 does not exist. Use 'forge asset context-graph version-list' to see available versions.
```

For advanced users who need to bypass this validation (for example, in automation scripts where versions may be created in parallel), use the `--skip-version-check` flag.

```bash
forge version-set upsert preview -s MyService -e production -a 5 -g 3 --skip-version-check --apply
```

{% hint style="warning" %}
Use `--skip-version-check` with caution. Pinning non-existent versions will cause runtime failures when the service is invoked.
{% endhint %}

### Compare Version Sets

```bash
forge version-set diff preview release -s MyService -e production

# JSON output for scripting
forge version-set diff preview release -s MyService -e production --json
```

Shows a side-by-side comparison of two version sets, highlighting differences.

### Promote Version Sets

```bash
# Promote to release (auto-backup creates release-previous for easy rollback)
forge version-set promote preview release -s MyService -e production --apply

# Skip auto-backup if needed
forge version-set promote preview release -s MyService -e production --no-backup --apply
```

{% hint style="info" %}
**Auto-backup.** When you promote to `release`, a backup is automatically created as `release-previous`. Use `--no-backup` to skip this safety measure.
{% endhint %}

### Rollback Version Sets

If a release causes issues, quickly revert to the previous configuration.

```bash
# Preview what would be rolled back (dry-run)
forge version-set rollback -s MyService -e production

# Execute the rollback
forge version-set rollback -s MyService -e production --apply
```

This is equivalent to `forge version-set promote release-previous release`, but makes the intent clearer and shows a comparison of the configurations.

```
Rollback 'release' to 'release-previous'
  Service: MyService (686d598b1234567890abcdef)
                         Configuration Comparison
┏━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓
┃ Field                 ┃ Previous (release-previous) ┃ Current (release) ┃
┡━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩
│ agent_version         │ 27                          │ 28                │
│ context_graph_version │ 3                           │ 4                 │
│ llm_preferences       │ 2 configured                │ 2 configured      │
└───────────────────────┴─────────────────────────────┴───────────────────┘

Dry-run mode. Use --apply to execute.
```

{% hint style="warning" %}
The `release-previous` version set is created automatically when you promote to `release`. If you've never promoted to release, or used `--no-backup`, the rollback command will fail with an error.
{% endhint %}

### Show Version Set Details

```bash
# Human-readable format
forge version-set show preview -s MyService -e production

# JSON output (for scripting)
forge version-set show preview -s MyService -e production --json
```

### Delete a Version Set

```bash
forge version-set delete test-old -s MyService -e dogfood --apply
```

{% hint style="warning" %}
Cannot delete `edge` or `release`. Cannot delete version sets referenced by simulation unit tests.
{% endhint %}

## Discovering Services (`forge service`)

Before working with version sets, you may need to discover what services exist and their current configuration. Use `forge service` commands to list and inspect services.

### List Services

```bash
# List all services in an environment
forge service list -e production

# Filter by tag (e.g., production, phone, voice)
forge service list -e production --tag phone

# JSON output for scripting
forge service list -e production --json
```

Output shows services with their tags and version set counts:

```
Services in production
Filtered by tag: phone

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┓
┃ Name                      ┃ ID          ┃ Tags                ┃ Version Sets ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━┩
│ Customer Support          │ 686d598b... │ phone, voice        │            3 │
│ Sales Assistant           │ 68bb4c7f... │ phone, production   │            2 │
└───────────────────────────┴─────────────┴─────────────────────┴──────────────┘
```

### Show Service Details

```bash
# Show full service configuration
forge service show "Customer Support" -e production

# JSON output for scripting
forge service show "Customer Support" -e production --json
```

Output includes linked assets and version set configuration:

```
Service: Customer Support
  ID: 686d598b1234567890abcdef
  Description: Voice support agent
  Active: Yes

Tags:
  - phone
  - voice

Linked Assets:
  Agent: support_agent (66e0d996f5a09fb3cf18ea73)
  Context Graph: support_context_graph (66e0d575f5a09fb3cf18ea5e)

Version Sets:
  Name       Agent Ver    CG Ver    LLM Config
  edge          latest    latest    defaults
  preview           28         4    2 set
  release           28         4    2 set

Related commands:
  forge version-set list Customer Support -e production
  forge asset agent version-list support_agent -e production
```

### Check Service Health Status

Monitor the health of services across your organization to catch configuration issues.

```bash
# Check status of active services only (default behavior)
forge service status -e production

# Include inactive/disabled services in the analysis
forge service status -e production --include-inactive

# Focus on production-tagged services only
forge service status -e production --production

# Show only services with issues
forge service status -e production --issues

# Filter by tag
forge service status -e production --tag phone

# JSON output for monitoring/alerting
forge service status -e production --json
```

**Detected Issues:**

* **Version set drift**: preview and release configurations differ.
* **Missing version sets**: production services missing preview or release.
* **Unpinned versions**: production services with non-edge version sets using `latest`.

**Example Output:**

```
Service Status in production

Summary:
  Total services: 8  # Only showing active services by default
  Production services: 3
  Services with issues: 2
    - With preview/release drift: 2

Services Needing Attention:

Name           ID          Active  Prod   Preview  Release  Issues
MyService      507f1f7...  Yes     Yes    Yes      Yes      preview/release drift
OtherService   508f2a8...  Yes     Yes    No       Yes      missing preview
```

{% hint style="info" %}
**Discovery workflow**: use `forge service list` to find services, `forge service status` to check health, and `forge service show` to inspect configuration before making changes with `forge version-set` commands.
{% endhint %}

## Discovering Asset Versions (`forge asset`)

Before pinning specific versions in a version set, you need to know what versions exist. Use `forge asset` commands to discover agent and context graph versions.

### List Agent Versions

```bash
# List versions for an agent by name
forge asset agent version-list MyAgent -e production

# List by agent ID
forge asset agent version-list 507f1f77bcf86cd799439011 -e production

# Show newest versions first
forge asset agent version-list MyAgent -e production --newest-first

# Get 50 most recent versions (pagination fetches multiple API pages automatically)
forge asset agent version-list MyAgent -e production --newest-first --limit 50
```

Output shows version numbers with creation timestamps:

```
Versions for Agent: MyAgent (507f1f77bcf86cd799439011)

┏━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┓
┃ Version ┃ Created          ┃ Description ┃
┡━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━┩
│       1 │ 2024-04-11 23:52 │ -           │
│       2 │ 2025-01-30 19:38 │ -           │
│       3 │ 2025-01-30 19:51 │ -           │
└─────────┴──────────────────┴─────────────┘
```

{% hint style="info" %}
**Sorting and pagination.** The `--newest-first` / `-d` flag sorts versions descending. When `--limit` exceeds the API's 10-per-page maximum, the CLI automatically paginates using `continuation_token` to fetch all requested results. Available on all `version-list` commands (agent, context-graph, behavior).
{% endhint %}

### List Context Graph Versions

```bash
forge asset context-graph version-list MyGraph -e production

# Newest first with limit
forge asset context-graph version-list MyGraph -e production -d --limit 20
```

Output includes a state count for each version:

```
Versions for Context Graph: MyGraph (66997b4d40fe08f84ba0d1d1)

┏━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┓
┃ Version ┃ Created          ┃ States ┃ Description          ┃
┡━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━┩
│       1 │ 2024-07-18 20:45 │     21 │ Initial version      │
│       2 │ 2024-08-07 17:06 │     22 │ Added new state      │
│       3 │ 2025-02-10 20:14 │     22 │ Bug fixes            │
└─────────┴──────────────────┴────────┴──────────────────────┘
```

### Show Version Details

```bash
# Agent version details
forge asset agent version-show MyAgent 3 -e production

# Context graph version details (shows state breakdown)
forge asset context-graph version-show MyGraph 2 -e production

# JSON output for scripting
forge asset agent version-show MyAgent 3 -e production --json
```

### Check Behavior Invocations

```bash
# See when/where a behavior was triggered
forge asset behavior invocations "Emergency Response Protocol" -e production

# JSON output for detailed analysis
forge asset behavior invocations "Emergency Response Protocol" -e production --json
```

### Workflow: Pin Discovered Versions

```bash
# 1. Discover latest agent version
forge asset agent version-list MyAgent -e production

# 2. Discover latest context graph version
forge asset context-graph version-list MyGraph -e production

# 3. Pin specific versions in a version set
forge version-set upsert preview -s MyService -e production -a 3 -g 2 --apply
```

{% hint style="info" %}
**Tip**: use `forge version-set upsert --latest` to automatically resolve and pin the current latest versions without looking them up manually.
{% endhint %}

## CLI Validation

All mutating version-set commands (`upsert`, `promote`, `delete`) run pre-flight validation before applying changes. Configurations are validated before they reach the remote API.

### Validation Rules

| Rule                                   | Scope               | Behavior                                                  |
| -------------------------------------- | ------------------- | --------------------------------------------------------- |
| Version existence check                | All upsert commands | Error if pinned agent/context graph version doesn't exist |
| Pinned versions required               | Production services | Error if agent/context graph version is `null`            |
| Cannot delete preview/release          | Production services | Error blocks deletion                                     |
| Preview required for release promotion | Production services | Error if preview doesn't exist                            |
| Voice-optimized LLMs only              | Voice channels      | Error if using non-voice-optimized models                 |
| Empty LLM prefs warning                | Voice channels      | Warning (non-blocking)                                    |
| Cost tier constraints                  | Economy presets     | Error if using premium LLMs                               |

{% hint style="info" %}
**Bypass validation**: use `--skip-version-check` to bypass version existence validation for advanced use cases.
{% endhint %}

### Example: Blocked Mutation

```bash
$ forge version-set upsert preview -s "Voice Service" -e production --apply

Error: Version set 'preview' uses a non-voice-optimized LLM.
Voice preset 'voice' requires voice-optimized LLMs for low latency.
Use 'forge channel llm-info --channel phone' to see valid models.

Validation failed. Fix errors before proceeding.
```

### Example: Warning (Non-blocking)

Warnings are displayed but don't block the operation.

```bash
$ forge version-set upsert test -s "Voice Service" -e dogfood --apply

Warning: Version set 'test' has empty llm_model_preferences. System defaults may
include non-voice-optimized LLMs. For voice preset 'voice', configure LLM preferences
explicitly using voice-optimized LLMs.

Create version set 'test'
  Service: Voice Service (66e0da39f5a09fb3cf18ea75)
  Agent version: latest
  Context Graph version: latest

Dry-run mode. Use --apply to execute.
```

{% hint style="info" %}
**Channel and preset tags** determine which validation rules apply. See [Channel Tagging](/developer-guide/operations/devops/channel-tagging.md) for details on configuring service tags.
{% endhint %}

## Practical Tips

### Naming Conventions

* Use lowercase letters, digits, `-`, or `_` only.
* Don't use `/`, `.`, or names starting with `$`.
* Examples: `personal-alex`, `test`, `preview`, `release`.
* **Drift control**: treat `release` as immutable except during deliberate promotion. Keep a changelog of which version set was promoted, when, and by whom.
* **Safety checks**: block deletion of sets referenced by simulations. Prefer deprecation and migration over deletion when many artifacts depend on a set.
* **Fast rollback**: use `forge version-set rollback` to quickly revert to the previous release configuration. The `release-previous` backup is created automatically when promoting to `release`.
* **Observability**: compare simulation metrics between `test`, `preview`, and `release` to quantify impact before promotion.

## API Touchpoints (Operational Behavior)

### API References

{% openapi src="<https://api.amigo.ai/v1/openapi.json>" path="/v1/{organization}/service/" method="post" %}
<https://api.amigo.ai/v1/openapi.json>
{% endopenapi %}

{% openapi src="<https://api.amigo.ai/v1/openapi.json>" path="/v1/{organization}/service/{service\_id}/version\_sets/{version\_set\_name}/" method="put" %}
<https://api.amigo.ai/v1/openapi.json>
{% endopenapi %}

{% openapi src="<https://api.amigo.ai/v1/openapi.json>" path="/v1/{organization}/service/{service\_id}/version\_sets/{version\_set\_name}/" method="delete" %}
<https://api.amigo.ai/v1/openapi.json>
{% endopenapi %}

* Service creation initializes `edge` and `release`.
* The upsert version set API cannot update `edge`, but can update `release` and custom sets.
* The delete version set API forbids deleting `edge` and `release`, and blocks deletion if a set is used in simulation unit tests.
* Conversation and real-time endpoints default to `release` when a version set isn't specified by the client.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.amigo.ai/developer-guide/operations/devops/version-sets-best-practices.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
