# Where Are Embedder Assets Stored in the WorkWeave Router Docker Image?

> Discover where embedder assets are stored in the WorkWeave Router Docker image. Learn how Go embed directive compiles assets into the router binary for read-only access via the artifacts variable.

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

---

**Embedder assets in the WorkWeave Router Docker image are compiled directly into the router binary using Go's `go:embed` directive, storing them in a read-only virtual filesystem accessible via the `artifacts` variable.**

The WorkWeave Router bundles machine learning embedder models directly into its Docker image using Go's native embedding capabilities. Unlike traditional deployments that rely on external volume mounts or runtime downloads, these assets live inside the compiled binary itself. This article examines the exact storage mechanism, source file locations, and runtime access patterns based on the official **workweave/router** repository source code.

## How Embedder Assets Are Embedded in the Binary

WorkWeave Router utilizes **Go's `go:embed` feature** to bake embedder assets directly into the compiled binary. This approach creates a self-contained Docker image where the assets reside in an **embedded `embed.FS`** filesystem rather than the container's physical filesystem.

According to the source code, the assets originate from two primary directories:

- `internal/router/percallband/artifacts`
- `internal/router/cluster/artifacts`

During the Docker build process, the Go compiler packages these directories into the binary, making them available through an `artifacts` variable of type `embed.FS`.

### Per-Call-Band Asset Embedding

The per-call-band embedder assets are declared in [`internal/router/percallband/head.go`](https://github.com/workweave/router/blob/main/internal/router/percallband/head.go) using specific file patterns:

```go
//go:embed artifacts/percall_band_markov.txt artifacts/percall_band_markov_emb.txt artifacts/percall_band_metadata.json
var artifacts embed.FS

```

This directive instructs the compiler to include the Markov model files and metadata into the binary's virtual filesystem. At runtime, the application accesses these files through the `artifacts` variable using standard filesystem operations.

### Cluster Asset Embedding

For cluster-based embedding operations, [`internal/router/cluster/artifacts.go`](https://github.com/workweave/router/blob/main/internal/router/cluster/artifacts.go) embeds the entire artifacts directory:

```go
//go:embed all:artifacts
var artifacts embed.FS

```

The `all:` prefix ensures that all files within the `artifacts` subdirectory are recursively included in the final binary.

## Runtime Access Patterns

When the Docker container runs, the embedder assets are accessed from within the binary's read-only virtual filesystem. The application code retrieves specific files using the `ReadFile` method on the embedded filesystem.

For example, loading the Markov model in [`internal/router/percallband/head.go`](https://github.com/workweave/router/blob/main/internal/router/percallband/head.go) works as follows:

```go
func loadMarkovModel() ([]byte, error) {
    // `artifacts` is the embedded filesystem created by go:embed
    return artifacts.ReadFile("artifacts/percall_band_markov.txt")
}

```

Similarly, the cluster scorer initialization receives the embedded resources through the `Embedder` interface, as seen in [`internal/router/cluster/scorer.go`](https://github.com/workweave/router/blob/main/internal/router/cluster/scorer.go):

```go
func NewScorer(bundle *Bundle, cfg Config, embed Embedder, providers map[string]struct{}) (*Scorer, error) {
    // The embedder is supplied by the binary; its assets come from the embedded `artifacts` FS
    if embed == nil {
        return nil, fmt.Errorf("cluster: embedder must not be nil")
    }
    // … further initialization …
}

```

Because the data is self-contained within the binary, no external files are written to the image's filesystem, eliminating dependency on volume mounts or network availability for asset retrieval.

## Docker Build Integration

The embedding process occurs during the Docker image build as defined in the repository's `Dockerfile`. The build copies the source tree—including the `internal/router/percallband/artifacts` and `internal/router/cluster/artifacts` directories—into the build context before compiling:

```dockerfile

# The Dockerfile copies source files and runs go build

COPY . /app
WORKDIR /app
RUN go build -o router .

```

When `go build` executes, it processes all `//go:embed` directives and compiles the asset bytes directly into the resulting `router` binary. The final Docker image contains only this single binary with assets baked inside, resulting in a minimal footprint without separate asset directories.

## Summary

- **Embedder assets** in the WorkWeave Router are stored using Go's `go:embed` directive, not as external files.
- Source assets reside in `internal/router/percallband/artifacts` and `internal/router/cluster/artifacts` before compilation.
- The `artifacts` variable of type `embed.FS` provides runtime access to the embedded files.
- The `Dockerfile` build process compiles assets directly into the router binary, creating a self-contained image.
- No external volume mounts or runtime downloads are required for the embedder to function.

## Frequently Asked Questions

### Are embedder assets stored as separate files in the Docker image?

No. The embedder assets are not separate files in the Docker image's filesystem. They are compiled directly into the router binary using `go:embed`, making them part of the binary's read-only virtual filesystem accessible only through the `artifacts` variable.

### How do I update the embedder assets in a running container?

You cannot update embedder assets in a running container without rebuilding the Docker image. Because the assets are baked into the binary at compile time, any changes to the model files in `internal/router/percallband/artifacts` or `internal/router/cluster/artifacts` require a new build of the workweave/router image.

### What is the performance impact of using go:embed for ML models?

Using `go:embed` provides fast, zero-copy access to embedder assets since the data resides in the binary's memory space. The `embed.FS` type offers efficient read operations through methods like `ReadFile`, though the assets remain read-only and immutable during runtime.

### Which directories contain the source embedder files before building?

Before the Docker build, source embedder files are located in two directories: `internal/router/percallband/artifacts` (containing files like [`percall_band_markov.txt`](https://github.com/workweave/router/blob/main/percall_band_markov.txt) and [`percall_band_metadata.json`](https://github.com/workweave/router/blob/main/percall_band_metadata.json)) and `internal/router/cluster/artifacts` (containing the full cluster embedder asset set).