# Install bundles

Write a self-contained install bundle for a service, with the Lys schema checked before anything is written.

One command writes a bundle into a new directory. With the Lys pair, the schema Lys holds is checked first. The bundled configuration is a snapshot, so changes later need a new bundle.

## Before you begin

Have a `service.json` you have run with `haematite serve`. If the install signs people in through Lys, have the issuer origin and the absolute path of the credential file.

## Write the bundle


1. Choose a bundle destination that does not yet exist, with an existing parent directory.

2. Run the install.

**Terminal**

```bash
haematite install --bundle /opt/haematite/ward-bundle --config service.json
```


3. With the Lys pair, the schema Lys holds for haematite is checked first. A drift refuses before anything is written.


The example omits the Lys pair and prints `lys_schema_unchecked`. To require the comparison, add `--lys-issuer` and `--lys-credential-file` as the command reference shows. An app credential is not an agent pass.

Write an install bundle.

```text
haematite install --bundle <new directory> --config <service.json> [--lys-issuer <origin> --lys-agent <id> --key-file <path>] [--lys-issuer <origin> --lys-credential-file <absolute path>]
```

- `--bundle <new directory>`: Where the bundle is written. Must not exist yet.
- `--lys-issuer, --lys-credential-file`: With this pair, the schema Lys holds is checked first and a drift refuses before anything is written.
- `--lys-issuer, --lys-agent, --key-file`: Preview main accepts all three together and configures the bundled launcher for that agent. The key path is canonicalised and must name a regular file; the key is not copied. These options are absent from the installed documentation binary.
- The bundled serve.json is a snapshot. Later socket or data directory changes need a new bundle directory.
- A repeat with changed inputs refuses as bundle_conflict.


## What the bundle contains

At main `84b9497a`, the bundle contains `bin/haematite`, any configured query and embedding workers, a rewritten `serve.json`, the haematite skill, Claude Code and Codex manifests, `.mcp.json` and both local marketplace files. Model files are not copied. Keep the configured model directory available separately.

Configured worker paths are rewritten to the copied workers. The data directory and service socket remain the configured store's paths. The installer does not copy store data or create another database. A bundle is not a backup.

Without agent options, generated registrations have no caller pass source and the preview installer prints `bundle_no_pass`. Add the caller's proof to the host's MCP registration for a protected store. With `--lys-issuer`, `--lys-agent` and `--key-file` together, the preview installer bundles the launcher and configures both registrations with the agent's canonical key-file path. The key itself is not copied. This agent proof is separate from `--lys-credential-file`, which checks the app schema. [Connect an agent](/haematite/getting-started/connect-an-agent/) describes the repository launcher and this boundary.

These Codex and marketplace bundle additions are preview source after `v0.20.1`. The installed binary used here wrote the older Claude Code layout and verified an identical second install. It did not execute the newer installer source, including agent configuration, so that layout and those options are source-derived.

## The bundled configuration is a snapshot

The `serve.json` inside the bundle is a snapshot taken at install time, with worker paths rewritten to the bundle. Later changes to the socket or the data directory need a new bundle directory. Repeating the command into the same directory with changed inputs is refused.

An identical installation verifies its manifest, payload hashes, modes and inventory before returning `already_installed`. Unexpected files, changed payloads or incomplete publication are named refusals. Read any stale-stage report and partial-publication evidence before choosing another destination.

> note
> The bundle installs no launch agent. How the service is kept running is the host's choice.
