# What Is the .cact File Format and How Does It Handle Engine Versioning in Needle 2?

> Explore the .cact file format and understand how it handles engine versioning in Needle 2. Learn about self-contained binary archives for model weights and inference engines.

- Repository: [Cactus Compute, Inc./needle](https://github.com/cactus-compute/needle)
- Tags: internals
- Published: 2026-08-25

---

**The `.cact` file is a self-contained binary archive that bundles trained model weights with the Needle 2 inference engine, and it is strictly version-locked to the specific engine build that created it.**

The `.cact` format serves as the portability layer for tuned models in the `cactus-compute/needle` repository. When you run **`needle build`**, the exporter in [`needle/model/export.py`](https://github.com/cactus-compute/needle/blob/main/needle/model/export.py) compresses weights—including any merged LoRA adapters—into a single archive. This file contains everything required for inference: no separate checkpoint files, tokenizers, or configuration files are needed.

## How the .cact Archive Is Created

The **`needle build`** command produces `.cact` files from base checkpoints and optional adapters. This process merges LoRA weights into the base model before serialization.

```bash

# Build a tuned .cact from a base checkpoint and LoRA adapter

needle build checkpoints/needle2.pkl \
    --lora checkpoints/needle_lora.pkl \
    --out tuned.cact

```

The exporter implementation lives in [`needle/model/export.py`](https://github.com/cactus-compute/needle/blob/main/needle/model/export.py). It handles weight consolidation, tensor layout optimization, and archive compression.

## Engine Version Locking and Compatibility

The `.cact` format is **intrinsically tied to the Needle 2 engine version** that created it. Engine upgrades can modify the internal archive structure—adding new sections for quantization metadata, changing tensor serialization formats, or revising header layouts.

Attempting to load an incompatible archive triggers a version-mismatch error. In [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py), the constructor catches this condition and raises:

```python
RuntimeError: "failed to load weights from ... – the .cact ..."

```

This check appears at line 86 of [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py), where the loader validates archive compatibility against the running engine's expected format.

### Documented Version Compatibility Policy

The [`doc/finetuning.md`](https://github.com/cactus-compute/needle/blob/main/doc/finetuning.md) file explicitly warns users about this constraint:

> "the `.cact` format is tied to the engine version, so an archive exported by an older package will not load. Rebuild it with the current package version."

This guidance appears at line 84 of the fine-tuning documentation. The policy is strict: **no backward compatibility guarantees** are provided across engine versions.

## Loading and Runtime Behavior

The `needle.Needle` class accepts a `.cact` file directly via the `weights` parameter, as documented in [`doc/apis.md`](https://github.com/cactus-compute/needle/blob/main/doc/apis.md). At runtime, the engine extracts and deserializes weights from the archive.

```python
import needle

# Load the tuned model—engine extracts weights automatically

agent = needle.Needle(weights="tuned.cact", tools=[...])
response = agent.run("Schedule a meeting for tomorrow at 10 am")
print(response["results"])

```

## Handling Version Mismatch Errors

Production code should catch and handle incompatible archive errors gracefully:

```python
try:
    agent = needle.Needle(weights="old_archive.cact")
except RuntimeError as e:
    if "failed to load weights" in str(e):
        print("⚠️  Incompatible .cact version – rebuild with current needle package.")
        # Re-export required: needle build <checkpoint> --out new_archive.cact

```

This pattern allows applications to detect stale archives and prompt for re-export rather than crashing ambiguously.

## Key Source Files

- **[`needle/model/export.py`](https://github.com/cactus-compute/needle/blob/main/needle/model/export.py)** — Implements the `.cact` archive creation and weight merging logic.
- **[`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py)** — Contains runtime loading, version validation, and error reporting (line 86).
- **[`doc/finetuning.md`](https://github.com/cactus-compute/needle/blob/main/doc/finetuning.md)** — Documents the version-locked nature of `.cact` and rebuild requirements (line 84).
- **[`doc/apis.md`](https://github.com/cactus-compute/needle/blob/main/doc/apis.md)** — Specifies the `weights` parameter accepting `.cact` paths.
- **[`tests/test_build.py`](https://github.com/cactus-compute/needle/blob/main/tests/test_build.py)** — Validates `.cact` construction and loading across engine versions.

## Summary

- **`.cact` is a binary archive** produced by `needle build` that bundles model weights with the inference engine.
- **The format is version-locked** to the specific Needle 2 engine build that created it.
- **Engine upgrades require archive regeneration** — older `.cact` files will not load and raise `RuntimeError`.
- **Key validation logic** resides in [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py) with user-facing documentation in [`doc/finetuning.md`](https://github.com/cactus-compute/needle/blob/main/doc/finetuning.md).

## Frequently Asked Questions

### Why does my .cact file fail to load after upgrading cactus-needle?

The `.cact` format embeds engine-specific serialization details that change between releases. The archive contains no backward-compatibility layer, so the loader in [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py) rejects mismatched versions with a "failed to load weights" error. Rebuild the archive using `needle build` with your current package version.

### Can I use a .cact file across different machines?

Yes, provided all machines run the **same version** of `cactus-needle`. The `.cact` file is portable but not version-agnostic. Copying between environments with mismatched engine versions will trigger compatibility errors.

### Does .cact include LoRA adapters or just base weights?

The archive includes **merged weights** — base weights plus any LoRA adapters specified during `needle build`. The exporter in [`needle/model/export.py`](https://github.com/cactus-compute/needle/blob/main/needle/model/export.py) performs this merge before serialization, so the `.cact` contains a single ready-to-run weight set.

### How can I verify which engine version created a .cact file?

The `cactus-needle` package does not expose archive version inspection APIs in the current release. Best practice is to regenerate `.cact` files whenever upgrading the package and to embed version metadata in your filenames or documentation (e.g., `model_v2.1.0.cact`).