# How WorkWeave Router Artifacts Are Versioned and Selected for Deployment

> Discover how WorkWeave Router versions artifacts in discrete directories and selects them for deployment using the ROUTER_CLUSTER_VERSION environment variable or the latest symlink.

- Repository: [Weave/router](https://github.com/workweave/router)
- Tags: internals
- Published: 2026-08-30

---

**WorkWeave Router versions routing artifacts in discrete directories under `internal/router/cluster/artifacts/` and selects them at runtime via the `ROUTER_CLUSTER_VERSION` environment variable, defaulting to a `latest` symlink that points to the current release.**

The `workweave/router` repository separates routing logic from the static data files—such as model rankings and cluster centroids—that drive its scoring decisions. Understanding how these artifacts are versioned and selected is critical for operators who need to pin, rollback, or validate routing behavior across deployments.

## Artifact Storage and Versioning Pattern

WorkWeave Router employs a file-system-based versioning strategy where each release is stored as a complete snapshot in a dedicated directory.

### Directory Structure and the Latest Symlink

Artifacts reside under `internal/router/cluster/artifacts/` in subdirectories named after semantic versions (for example, `v0.75`, `v0.74`, or `v0.71`). A special symbolic link named `latest` points to the most current version directory. Each version folder contains the complete set of static data required for routing decisions:

- [`model_registry.json`](https://github.com/workweave/router/blob/main/model_registry.json) – Model metadata and routing rules
- [`rankings.json`](https://github.com/workweave/router/blob/main/rankings.json) – Pre-computed ranking configurations  
- [`metadata.yaml`](https://github.com/workweave/router/blob/main/metadata.yaml) – Version-specific configuration attributes
- `centroids.bin` – Binary cluster centroid data

This structure is defined and managed through the constant `LatestVersion = "artifacts/latest"` in [[`internal/router/cluster/artifacts.go`](https://github.com/workweave/router/blob/main/internal/router/cluster/artifacts.go)](https://github.com/workweave/router/blob/main/internal/router/cluster/artifacts.go), which serves as the canonical reference for the default artifact set.

## Runtime Version Selection Mechanism

The router determines which artifact directory to load through a cascading resolution strategy centered on environment variable configuration.

### The ROUTER_CLUSTER_ENVIRONMENT Variable

At boot time, the composition root in [[`cmd/router/main.go`](https://github.com/workweave/router/blob/main/cmd/router/main.go)](https://github.com/workweave/router/blob/main/cmd/router/main.go) (lines 568 and 1309) invokes `config.GetOr("ROUTER_CLUSTER_VERSION", cluster.LatestVersion)` to resolve the active version. This call checks for the environment variable `ROUTER_CLUSTER_VERSION` and returns its value; if the variable is unset, it falls back to the `cluster.LatestVersion` constant.

Operators can observe the effective version through the Admin API, specifically in [[`internal/api/admin/version.go`](https://github.com/workweave/router/blob/main/internal/api/admin/version.go)](https://github.com/workweave/router/blob/main/internal/api/admin/version.go) (line 33) and [[`internal/api/admin/config.go`](https://github.com/workweave/router/blob/main/internal/api/admin/config.go)](https://github.com/workweave/router/blob/main/internal/api/admin/config.go) (line 42), which expose the resolved version string via the `/admin/v1/version` and `/admin/v1/config` endpoints.

### Version Resolution Flow

1. **Environment Check** – The router reads `ROUTER_CLUSTER_VERSION` from the process environment.
2. **Default Application** – If undefined, the system uses `"artifacts/latest"`, which resolves to the symlinked directory.
3. **Path Construction** – The router constructs the absolute path by joining the base artifacts directory with the resolved version string.
4. **File Loading** – The system loads [`model_registry.json`](https://github.com/workweave/router/blob/main/model_registry.json), [`rankings.json`](https://github.com/workweave/router/blob/main/rankings.json), and associated files from the computed path into memory.

## Validation and Boot-Time Safety

The router implements fail-fast validation to prevent deployment errors caused by missing artifacts. In [[`cmd/router/main.go`](https://github.com/workweave/router/blob/main/cmd/router/main.go)](https://github.com/workweave/router/blob/main/cmd/router/main.go) at line 1408, the startup sequence verifies that the requested version directory exists and contains the required artifact files. If the validation fails—for example, if `ROUTER_CLUSTER_VERSION` is set to `v0.99` but that directory does not exist—the process exits immediately with a clear error message rather than attempting to operate with incomplete data.

## Deployment Configuration Examples

### Deploy with the Latest Artifacts

To use the current release without pinning to a specific version, omit the environment variable or explicitly set it to the latest sentinel:

```bash

# Uses the artifacts/latest symlink

export ROUTER_DEPLOYMENT_MODE=selfhosted
./router

# Or explicitly

export ROUTER_CLUSTER_VERSION=artifacts/latest
./router

```

### Pin to a Specific Version

For reproducible deployments or rollback scenarios, specify an exact version directory:

```bash
export ROUTER_CLUSTER_VERSION=v0.71
./router

```

This configuration directs the router to load files from `internal/router/cluster/artifacts/v0.71/` instead of the `latest` symlink.

### Verify Active Version via Admin API

Once running, confirm the loaded artifact version:

```bash
curl http://localhost:8080/admin/v1/version

# Expected output: {"cluster_version":"v0.71","latest":false}

```

### Programmatic Resolution in Go

For custom tooling or sidecar processes, resolve the artifact path using the same logic as the router:

```go
import (
    "path/filepath"
    "github.com/workweave/router/internal/config"
    "github.com/workweave/router/internal/router/cluster"
)

func resolveArtifactPath() string {
    // Mirrors cmd/router/main.go line 568
    version := config.GetOr("ROUTER_CLUSTER_VERSION", cluster.LatestVersion)
    return filepath.Join("internal/router/cluster/artifacts", version)
}

```

## Summary

- **File-system versioning** – Artifacts are stored in discrete directories (`v0.75`, `v0.71`, etc.) under `internal/router/cluster/artifacts/`, with a `latest` symlink providing a stable reference.
- **Environment-driven selection** – The `ROUTER_CLUSTER_VERSION` variable controls which directory loads, defaulting to `cluster.LatestVersion` ("artifacts/latest") when unset.
- **Fail-fast validation** – Boot-time checks in [`cmd/router/main.go`](https://github.com/workweave/router/blob/main/cmd/router/main.go) (line 1408) ensure the requested version exists before the router begins accepting traffic.
- **Admin API visibility** – The active version is exposed via [`internal/api/admin/version.go`](https://github.com/workweave/router/blob/main/internal/api/admin/version.go) and [`internal/api/admin/config.go`](https://github.com/workweave/router/blob/main/internal/api/admin/config.go) for operational monitoring.

## Frequently Asked Questions

### What happens if ROUTER_CLUSTER_VERSION points to a non-existent version?

The router performs validation during the initialization sequence in [`cmd/router/main.go`](https://github.com/workweave/router/blob/main/cmd/router/main.go) (line 1408). If the specified directory does not exist under `internal/router/cluster/artifacts/`, the process exits immediately with an error, preventing the deployment from serving traffic with missing data.

### How does the "latest" symlink work in practice?

The `latest` directory is a symbolic link maintained in the repository that points to the most recent version folder (such as `v0.75`). According to [`internal/router/cluster/artifacts.go`](https://github.com/workweave/router/blob/main/internal/router/cluster/artifacts.go), the constant `LatestVersion` is defined as `"artifacts/latest"`, ensuring that deployments without an explicit version pin automatically pick up the newest artifact set on restart.

### Can I hot-swap artifact versions without restarting the router?

No. The artifact version is resolved once at boot time in [`cmd/router/main.go`](https://github.com/workweave/router/blob/main/cmd/router/main.go) (lines 568 and 1309) and loaded into memory. To change versions, you must restart the process with the desired `ROUTER_CLUSTER_VERSION` value or update the `latest` symlink and redeploy.

### What files are included in a versioned artifact directory?

Each version folder contains the complete static dataset required for routing: [`model_registry.json`](https://github.com/workweave/router/blob/main/model_registry.json) for model definitions, [`rankings.json`](https://github.com/workweave/router/blob/main/rankings.json) for scoring configurations, [`metadata.yaml`](https://github.com/workweave/router/blob/main/metadata.yaml) for version attributes, and `centroids.bin` for binary cluster data. The router loads all these files from the selected `internal/router/cluster/artifacts/<version>/` path during startup.