> ## Documentation Index
> Fetch the complete documentation index at: https://usefused.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Testing and compilation

> Run unit tests, smoke tests, evals, CI checks, and compile standalone artifacts.

Harnest owns the environment and compiled application used by every test lane. Authored tests exercise the selected ADK or LangGraph target without importing Harnest or manually loading build artifacts.

| Lane    | Command                          |         Network | Best for                           |
| ------- | -------------------------------- | --------------: | ---------------------------------- |
| Unit    | `harnest test AGENT_DIR`         |              No | Agent logic and local tools        |
| Smoke   | `harnest test AGENT_DIR --smoke` |         Allowed | Live models, MCP, and API journeys |
| Evals   | `harnest test AGENT_DIR --evals` | Depends on eval | Quality and tool trajectories      |
| Compile | `harnest compile AGENT_DIR`      |              No | Reproducible standalone artifact   |

## Review changes in Agent Builder

Playground provides conversation testing, traces, and evaluation suites. Agent authoring, visual editing, and MCP setup live in the standalone Harnest Studio; Playground no longer includes an embedded Studio tab.

Harnest Studio is bundled with the release CLI, including its web server, browser assets, and compiled Build with AI assistant. Start it from the folder you want to use as your workspace:

```bash theme={null}
harnest studio
```

If `--workspace` is omitted, Studio uses your current working directory. Select a different existing folder or port explicitly:

```bash theme={null}
harnest studio --workspace /path/to/agents --port 1940
```

Studio discovers agent folders containing `config.yaml` recursively within the workspace. For example, `harnest studio --workspace examples` loads both standalone examples and nested agents such as `self-serve/agents/helpdesk`. The project selector shows relative folder paths, and **Refresh** picks up newly added agents. Discovery stops at each agent root and skips hidden folders, build output, dependencies, virtual environments, and symbolic links. Workspaces exceeding 10,000 scanned folders require a more specific root. Use **Open folder** to add an individual agent outside the workspace.

Open the private launch URL printed in the terminal. Studio binds to `127.0.0.1` on port 1940 by default. The first launch prepares an isolated runtime from the bundled release; Python and dependency downloads may require network access. Later launches reuse that runtime. Agent builds retain their own locked dependency environments. The compiled assistant is included and does not compile on first use; configure model-provider credentials to use **Build with AI**.

Keep the command running while using Studio. Ctrl+C stops its local server and supervised processes. An explicit `--python` or `HARNEST_PYTHON` uses that interpreter instead, which must already contain Studio and its matching dependencies.

In the standalone Agent Builder, **Build with AI** creates a source proposal for review. The **Source context** selector chooses the initial files shared with your configured model provider. **Allow AI to read related project source** is enabled by default in the UI; turn it off to share only selected files.

With related source access enabled, the assistant can request additional files from the current project's source inventory. It reads the actual contents and regenerates the proposal before review. Hidden files, environment files, generated directories, and symbolic links are excluded. Each proposal lists the source files read, with a limit of 24 files and 160 KiB of context across at most two additional reading rounds.

Choose **Review changes**, inspect the before and after contents, then **Apply to project**. Studio checks source revisions before writing, so concurrent edits are preserved. A proposal does not execute commands or connect to a database. Use **Build agent** and the **Run & test** menu to validate changes after applying them.

### Connect and create MCP servers

Open **MCP connections** in the workspace sidebar. Choose **Add HTTP MCP endpoint** to connect an existing Streamable HTTP server, or enter your Fused Engine URL and choose **Connect Fused**. Complete sign-in in the same browser, then reopen the dialog. Management credentials remain in Studio's server memory; restarting Studio requires reconnecting.

After connecting, choose **Add existing Fused MCP** to select an active server version, or **Create MCP with Fused** to select workspace services and their operations. Choose the owning agent, the Fused bucket, and an optional owner team. An empty operation selection is rejected; **All operations** must be selected explicitly. Provider connections and bucket permissions must already be configured in Fused.

**Review connection** shows the exact provisioning configuration and source diffs. **Apply connection** can create a server, issue a seven-day execution token, and write the owning agent's MCP Client. It also adds runtime environment references to an existing `harnest-deployment.yaml`; select a deployment agent name if that manifest contains multiple agents. Studio checks source revisions before provisioning. If the remote result is uncertain, check Fused's server list before preparing another review; Studio does not replay that mutation automatically.

Runtime credentials are stored outside project source in owner-only files under `~/.harnest/studio-credentials`. Set `HARNEST_BUILDER_CREDENTIALS_DIR` before starting Studio to choose another private directory. Studio supplies these bindings only to commands for that project and redacts execution tokens from command output. Restart an already-running agent after applying a connection. For commands launched outside Studio or deployments managed elsewhere, provide the variables shown in the review through your own secret manager. Disconnecting Fused clears management access and pending reviews; it does not revoke existing MCP execution tokens.

**Build with AI** uses the same discovery and review backend. Enable **Allow Fused service and operation metadata to be shared with the model** to let it inspect connected workspace capabilities. This is separate from source-sharing permission and is off by default. The model receives discovered metadata and proposes an MCP plan; it never receives OAuth grants or execution credentials and cannot apply the plan itself.

### Delete and restore capabilities

Select a capability on the Agent Builder canvas, then choose **Delete capability…** in the inspector. Expand a category to select an individual tool, agent, skill, or other source capability. The preview lists the affected files and possible code references. Deleting a package entrypoint, such as a skill's `SKILL.md` or a subagent's `agent.py`, removes the complete package and its supporting assets from discovery. Root project files and category folders cannot be deleted this way.

Deletion moves source into `.harnest/builder-deleted/` inside the project. **Deleted capabilities** above the canvas lists recoverable items after refresh or restart. Choose **Restore** to return an item to its original location; Studio refuses to overwrite a new file or folder there. Stop running builds and previews before deleting or restoring a capability.

Explicit imports, graph node references, schedules, and other authored wiring are not rewritten. Review the possible references and build the agent after updating them. Deleting source does not remove a deployed container, an external service, or its database data.

## Unit tests

Run the default offline lane:

```bash theme={null}
harnest test AGENT_DIR
```

Harnest compiles the project, then collects `tests/unit/test_*.py`.

| Fixture | Value                        |
| ------- | ---------------------------- |
| `agent` | Selected framework target    |
| `tools` | Read-only map of local tools |

Unit tests should not call models, MCP servers, or other networks. This is a convention, not an OS sandbox.

## Smoke tests

Live runtime checks belong in `tests/smoke/test_*.py` and run only when selected:

```bash theme={null}
harnest test AGENT_DIR --smoke
```

The unit lane runs first. Smoke tests add a FastAPI `client` and a `smoke` fixture.

| Method               | Returns                   |
| -------------------- | ------------------------- |
| `smoke.respond(...)` | One neutral JSON response |
| `smoke.stream(...)`  | Ordered SSE event objects |

Smoke tests may spend time or money and use real credentials. Run them deliberately.

## Evaluations

Run eval assets after the Python tests:

```bash theme={null}
harnest test AGENT_DIR --evals
harnest test AGENT_DIR --smoke --evals
```

ADK and LangGraph projects share official ADK `EvalSet` assets and metrics. Harnest prints a complete structured JSON `EvalRunResult` by default, and `--eval-output FILE` writes the same payload for retention. An explicit result file is still written with `--no-output`.

<Card title="Build evaluations" icon="flask" href="/docs/harnest/build/evaluations">
  Choose metrics, author eval sets and simulations, configure services, and inspect complete results.
</Card>

## Compile an artifact

Compile validated source into a standalone runtime directory:

```bash theme={null}
harnest compile AGENT_DIR --output .harnest/my-agent
```

| Artifact file               | Purpose                                 |
| --------------------------- | --------------------------------------- |
| Preserved source            | Your agent code                         |
| Generated adapters          | Selected framework integration          |
| `harnest-manifest.json`     | Versions, mode, and source identity     |
| `harnest-build-report.json` | Included files, reasons, and byte sizes |
| `server.yaml`               | Mutable runtime settings                |
| `harnest-agent`             | Launcher                                |

Compiled directories are reproducible output. Do not edit or commit them.

### Conditional dependencies

| Source                             | Compile behavior                                                                |
| ---------------------------------- | ------------------------------------------------------------------------------- |
| Root `pyproject.toml`              | Resolves application dependencies                                               |
| Harnest Extension `pyproject.toml` | Joins the same dependency solve and lock                                        |
| Public `@task`                     | Uses built-in Harnest workers; provider dependencies come from project metadata |
| Active `mcp/*.py`                  | Adds the selected framework's MCP adapter                                       |
| `serve`, `run`, or `test`          | Selects the shared development profile                                          |
| `test --evals`                     | Selects the Google ADK evaluation profile                                       |

Harnest resolves the selected environment before importing the agent or its
Harnest Extensions. Production runtime, development, and eval use independent
locks so compiled deployment artifacts do not inherit development-only packages.

## Select compilation dependencies

Add `harnest-compile.yaml` beside your agent's `config.yaml` to select optional dependency groups:

```yaml harnest-compile.yaml theme={null}
version: 1
extras: [crm]
```

Define the selected extra in the agent's configured `pyproject.toml`. Package versions stay in ordinary Python metadata:

```toml pyproject.toml theme={null}
[project]
name = "sales-agent"
version = "1.0.0"
dependencies = ["httpx>=0.28,<1"]

[project.optional-dependencies]
crm = ["acme-crm-sdk>=2,<3"]
analytics = ["acme-analytics-sdk>=1,<2"]
```

In this example, compilation selects `crm`. It does not select `analytics` unless another requirement needs it. Both `compile` and `runtime build --agent` read these declarations. Ordinary `run`, `serve`, reload, and agent tests do not apply them.

| Field     | Behavior                                                                                                              |
| --------- | --------------------------------------------------------------------------------------------------------------------- |
| `version` | Required; use `1`.                                                                                                    |
| `extras`  | Optional list of exact keys from the root project's `[project.optional-dependencies]`. Unknown extras fail the build. |

Harnest retains base project requirements, Harnest Extension requirements, the selected framework, and the required transitive dependencies. It keeps complete installed packages, including their metadata, resources, and native libraries. It does not remove Python modules based on observed imports. Put optional integrations in separate extras to avoid requiring every integration in every build.

### Project files and compiled content

Compilation includes Python source, the standard project configuration and dependency metadata, root and nested-subagent `instructions.md`, evaluation declarations, and complete installed skills, extensions, and Agent Plugins. Installed packages retain their assets together so their runtime behavior is preserved. Exclusions for secrets, generated state, and virtual environments still apply.

Other project content, such as teammate guides, runbooks, PDFs, setup notes, and company authoring configuration, stays in the generated project and does not enter the compiled agent. This applies with or without a compile manifest. Ordinary `run`, `serve`, reload, and agent tests continue using the authored project content.

`harnest-compile.yaml` accepts only `version` and `extras`. A `resources` field is rejected, including an empty list. There is no general file-inclusion setting. Harnest does not infer arbitrary file reads from Python code.

Use an agent template to create standard `instructions.md` or skill content when the agent needs guidance. These conventional files compile automatically; teammate documentation does not become instructions or skills simply because a pack copied it into the project.

Directory compilation with selected optional requirements uses a separate compile environment and `harnest-compile.lock`. Use `harnest env sync AGENT_DIR --profile compile` to prepare or refresh that environment explicitly. It does not replace the ordinary runtime or development environment. Native runtime builds continue to honor current production locks as constraints and retain their own resolved lock in the runtime pack.

[Project packs](/docs/harnest/build/project-packs/create#declare-compilation-dependencies) can generate and migrate these declarations through their existing file and YAML operations. Pack authoring and migration tools stay in the authoring environment unless you explicitly declare them as runtime dependencies.

### Inspect a build report

| Output             | Report location                                      |
| ------------------ | ---------------------------------------------------- |
| Compiled directory | `OUTPUT/harnest-build-report.json`                   |
| Runtime pack       | `PACK/harnest-build-report.json`                     |
| Native executable  | `EXECUTABLE.build-report.json` beside the executable |

Agent reports list selected extras, retained files, inclusion reasons, and byte sizes. Runtime reports list declared dependency roots and owners, resolved package versions, installed package sizes, declared package requirements, and the complete runtime file inventory. Packages without a direct root declaration are labeled as part of the resolved transitive closure. Declared requirements may contain inactive environment markers; they are metadata, not a separately resolved dependency graph.

Runtime `logicalBytes` counts retained file bytes, while `uniqueObjectBytes` counts each stored object once within that runtime. These figures exclude the report itself and filesystem overhead; they do not measure incremental disk usage across other packs. Executable reports also show the executable's actual size and whether its runtime is embedded. Overlapping package ownership can make per-package sizes overlap.

Shared runtimes resolve the combined selected requirements of all listed agents. Identical files continue sharing the existing content-addressed store and launch cache. Changing selected requirements requires rebuilding runtime coverage; changing included agent content only requires recompiling the agent.

## Build native executables

Build native agent executables on Linux, macOS, or Windows for the build machine's operating system and architecture. The destination needs no installed Harnest, Python, or package manager. Model endpoints, credentials, external tools, and backing services still need to be available. Native dependencies retain their operating-system compatibility requirements; build on a compatible deployment baseline.

Choose how to ship the dependencies:

| Mode                       | Build command                                                                         | Deployment                                                                               |
| -------------------------- | ------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| Attached runtime           | `harnest compile ./sales --runtime ./dist/shared-runtime --output ./dist/sales-agent` | Ship the agent and its runtime pack separately. Several agents can attach the same pack. |
| Embedded runtime           | Add `--embed-runtime` to the command above                                            | Ship one executable containing the agent and runtime.                                    |
| Automatic embedded runtime | `harnest compile ./sales --format executable --output ./dist/sales-agent`             | Resolve a runtime for this agent and embed it automatically.                             |

On Windows, build on a Windows host and use an output filename ending in `.exe`. For example, in PowerShell:

```powershell theme={null}
harnest runtime build --agent .\sales --agent .\support --output .\dist\shared-runtime
harnest compile .\sales --runtime .\dist\shared-runtime --output .\dist\sales-agent.exe
harnest compile .\support --runtime .\dist\shared-runtime --output .\dist\support-agent.exe
.\dist\sales-agent.exe --runtime .\dist\shared-runtime run "Help with my order"
```

Runtime packs target the build host; a Linux or macOS pack cannot be attached to a Windows executable. Packaged Python console tools remain usable after moving the deployment directory.

`--runtime` validates and references the pack. It does **not** copy dependencies into the agent executable unless you also pass `--embed-runtime`. Ordinary `compile` without these options still produces the existing Python artifact directory.

### Share dependencies across agents

Run these commands from the directory containing your agent folders:

```bash theme={null}
harnest runtime build \
  --agent ./sales \
  --agent ./support \
  --output ./dist/shared-runtime

harnest compile ./sales \
  --runtime ./dist/shared-runtime \
  --output ./dist/sales-agent

harnest compile ./support \
  --runtime ./dist/shared-runtime \
  --output ./dist/support-agent
```

The runtime builder resolves all listed agents' production dependencies together, including their Harnest Extensions, selected frameworks, and MCP adapters. Existing current `harnest-runtime.lock` files constrain the solve; stale locks require an environment sync first. Agents without a production lock resolve from their dependency declarations and framework pins. The pack retains the resulting hash-locked dependency record. Resolution conflicts fail the build: use separate packs for incompatible agents. The agents must request the same Python version.

Build dependencies may need network access. Executables never download Python or install packages at startup. Installed release CLIs include the native launcher, so building an executable does not require Go. Contributor builds use Go to build the launcher and can supply a locally built Harnest wheel with `runtime build --wheel FILE`.

Keep build output outside the agent source, or under its `.harnest/` directory. Runtime output directories must be new: builds do not overwrite existing packs. When dependencies change, build a new pack and recompile the agents that should use it.

### Attach a runtime when launching

```bash theme={null}
./dist/sales-agent --runtime ./dist/shared-runtime serve --port 8080
./dist/support-agent --runtime ./dist/shared-runtime run "Help with my order"
```

Place launcher options before `serve` or `run`. Relative paths resolve from the working directory. Set `HARNEST_AGENT_RUNTIME` instead of passing `--runtime` to every invocation. The launcher verifies the exact runtime digest and platform before loading agent code; a different pack is rejected even if it has a similar name.

The `run` command requires `spec.interfaces.cli: true` when the agent is compiled. It accepts a positional message or reads stdin when the message is omitted. Pass `run --help` or `serve --help` for command options.

Provide credentials through the deployment environment. Authored `spec.environment` values act as defaults; explicitly supplied environment variables take precedence. Use `--server-config FILE` before the command to replace the packaged server settings for one process. Keep durable state and deployment configuration outside the executable and runtime cache.

### Deduplicate dependency storage

Dependency files are stored by content and executable classification (POSIX executable permissions or Windows program extensions). Identical files share disk storage within a pack, across packs built with the same object store, and across materialized runtime trees in the launch cache. Each agent still runs in its own process.

By default, runtime builds use `.harnest-runtime-objects` beside the output directory. Use `runtime build --store DIRECTORY` to share one build store across other output locations. Packs contain their own object links and remain usable after the build store is removed; copy the complete runtime pack when deploying it. Hardlink-aware copying preserves sharing between multiple packs. Ordinary copies may duplicate their on-disk bytes until the launch cache deduplicates them.

Launchers use a shared cache under the operating system's user cache directory. Set `HARNEST_AGENT_CACHE` to choose a deployment cache. Files are verified before reuse and published atomically. Hardlinks provide physical deduplication on the same filesystem; filesystems or locations that cannot share hardlinks use a verified copy fallback. Put the pack, object store, and cache on the same hardlink-capable filesystem for maximum disk sharing. On Windows, use the same NTFS volume. Windows file aliases are packaged as shared regular files, so deployment does not require permission to create symbolic links. Windows objects use ordinary writable file attributes to allow independent hardlink cleanup; their contents are still checked against the manifest before reuse.

Embedding the same runtime into several executables necessarily repeats those bytes in the executable files. Use attached runtimes when distribution size matters. Embedded executables also materialize dependencies in the shared launch cache.

## CI

A minimal offline CI sequence is:

```bash theme={null}
harnest env sync AGENT_DIR --profile development --frozen
harnest test AGENT_DIR
harnest env sync AGENT_DIR --frozen
harnest compile AGENT_DIR --output .harnest/my-agent
```

Add smoke or eval lanes only when CI has the required services and credentials. For Harnest source changes, follow [Development standards](/docs/harnest/reference/development-standards).
