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

# Mobpack and Web Deployment

> Portable multi-agent deployment with signed .mobpack artifacts and browser-target web bundles.

`mobpack` is the portable runtime artifact for mobs. You build it once, then
deploy it with an objective, invoke a typed callable flow, or build a browser
bundle.

<Note>
  A mobpack is not a VM, container, or complete host image. It carries a mob
  definition and reviewed runtime assets. It does not carry the Meerkat binary,
  OS packages, provider credentials, secret environment values, or operator
  network policy.
</Note>

## What this guide is for

Use this guide when you want to:

* package a mob into a portable artifact
* sign and validate that artifact
* invoke it consistently across CLI, service, and browser targets

## What you get

* Single-file artifact: `.mobpack`
* Optional signing and trust verification
* Deterministic `inspect` and `validate` boundaries
* Closed capability and target-surface declarations
* Typed, capability-gated deploy defaults
* Optional adaptive FlowMaster policy and schema assets
* Typed callable invocation (`mob run`) and browser bundle target (`mob web build`)

## Directory to artifact

```bash theme={null}
rkat mob pack ./mobs/release-triage -o ./dist/release-triage.mobpack
rkat mob inspect ./dist/release-triage.mobpack
rkat mob validate ./dist/release-triage.mobpack --trust-policy permissive
```

Expected source files:

* `manifest.toml`
* `definition.json`
* optional `skills/`, `hooks/`, `mcp/`, `config/defaults.toml`
* optional adaptive content under `adaptive/` and `schemas/`

The runtime recognizes `skills/`, `hooks/`, `mcp/`, `config/`, `adaptive/`,
and `schemas/` as typed asset sections, plus the root manifest, definition,
and signature records. Other safe files can be carried and are covered by the
digest, but the runtime does not interpret them as assets. Paths are
canonicalized and unsafe or duplicate entries fail closed. Required capability
tokens and surface selectors use closed typed vocabularies, so an unknown
token fails instead of silently downgrading execution.

### Manifest contract

A minimal manifest names and versions the artifact. Optional sections declare
capabilities, model aliases, profile assets, supported target surfaces, and
adaptive metadata:

```toml theme={null}
surfaces = ["cli", "rpc"]

[mobpack]
name = "release-triage"
version = "1.0.0"
description = "Release regression triage team"

[requires]
capabilities = ["comms", "skills"]

[models]
lead_model = "gpt-5.5"

[profiles.lead]
model = "lead_model"
skills = ["skills/lead.md"]
```

Known surface selectors are `cli`, `rpc`, `rest`, `mcp`, and `web`. Skill paths
must be canonical paths under `skills/`. `definition.json` remains the one
`MobDefinition` authority; the manifest describes packaging and deployment
requirements around it.

### Deploy defaults are an allow-list

`config/defaults.toml` is parsed into `MobpackDeployPolicy`, not merged into the
host's general `Config`. A pack may declare only:

* top-level `max_tokens` for the per-turn output cap
* `[models]` defaults for `anthropic`, `openai`, and `gemini`
* `[budget]` values `max_tokens`, `max_duration_secs`, and `max_tool_calls`
* `[compaction]` values `auto_compact_threshold`, `recent_turn_budget`, `max_summary_tokens`, and `min_turns_between_compactions`

For example:

```toml theme={null}
max_tokens = 4096

[models]
openai = "gpt-5.5"

[budget]
max_tokens = 200000
max_duration_secs = 900
max_tool_calls = 200

[compaction]
auto_compact_threshold = 64000
recent_turn_budget = 12
max_summary_tokens = 4096
min_turns_between_compactions = 4
```

Compaction knobs require `session_compaction` in `[requires].capabilities` and
on the selected runtime. Unknown sections and fields fail closed. In
particular, a pack cannot set realm bindings, self-hosted endpoints, provider
tool keys, comms credentials, hooks, shell security, storage, retry, or general
agent/tool configuration. Operator realm and environment layers remain
authoritative; pack values are deployment defaults, not overrides of
operator-owned truth.

The definition also cannot smuggle realm references. Optional hook and MCP
assets are declarations that still require compatible host capabilities and
host-local resources. Keep secrets outside the archive.

## Signed packs and trust policy

Sign at pack time:

```bash theme={null}
rkat mob pack ./mobs/release-triage -o ./dist/release-triage.mobpack --sign ./keys/release.key --signer-id release@example.com
```

Signing embeds the public key but does not install the signer in the verifier's
trust configuration. Use permissive mode for this immediate local path, then
switch to strict after installing the signer as trusted:

```bash theme={null}
rkat mob run ./dist/release-triage.mobpack --prompt "triage release regressions" --trust-policy permissive
```

Trust policy resolution:

1. CLI `--trust-policy`
2. `RKAT_TRUST_POLICY`
3. config `trust.policy`
4. default `strict` (fail closed; accepting unsigned or unknown-signer packs requires an explicit `permissive` opt-in)

Strict mode rejects:

* unsigned packs
* unknown signers
* invalid signatures
* signer key mismatches

Permissive mode accepts unsigned packs and valid signatures from unknown
signers with warnings. It still rejects an invalid signature, digest mismatch,
or signer-key mismatch. Permissive means relaxed signer enrollment, not skipped
integrity.

## Run Modes

Deploy a pack with one objective and optional host-owned model or budget
overrides:

```bash theme={null}
rkat mob deploy ./dist/release-triage.mobpack \
  "triage latest incidents" \
  --max-duration 15m \
  --trust-policy permissive
```

Invoke a pack as a typed callable. When the pack includes
`schemas/main-input.json`, parameters are validated against it before the flow
starts. The resulting object is the flow's `params` context, so step messages
can read values such as `{{ params.prompt }}`. `--prompt` is sugar for
`--param prompt=<text>`:

```bash theme={null}
rkat mob run ./dist/release-triage.mobpack \
  --flow main \
  --param severity='"high"' \
  --prompt "triage latest incidents" \
  --trust-policy permissive
```

Pack runs use the realm's durable mob and run stores. `--detach` requires a
callable flow and returns its run id; inspect the persisted mob and run
afterward:

```bash theme={null}
rkat mob run ./dist/release-triage.mobpack \
  --flow main \
  --prompt "triage latest incidents" \
  --param severity='"high"' \
  --detach \
  --trust-policy permissive
rkat mob runs release-triage --json
rkat mob attach release-triage <RUN_ID>
```

<Warning>
  `--detach` persists the run record but does not transfer execution custody to
  a daemon. The flow executes only while that CLI process lives. After the
  process exits, the next mob hydration converges any unfinished run to
  `canceled` with execution custody lost. Use a long-lived host process when the
  work itself must continue independently.
</Warning>

When the mob already exists in the realm, the target can be its mob id instead
of a file path. That path invokes the installed definition and does not reload
or re-verify a pack.

## Adaptive mobpacks

An adaptive mobpack declares `[adaptive]` with a FlowMaster profile, objective
class, SHA-256 policy digest, required schemas, and target surfaces. It also
supplies:

* `adaptive/policies.toml`
* `adaptive/flowmaster.prompt.md`
* `schemas/registry.json` and every registered required schema

`rkat mob pack` stamps the `adaptive_flow` requirement and generates the
canonical `adaptive/layer-decision.schema.json`. Validation rejects a policy
digest mismatch, incomplete policy with any zero limit, missing registered
schema, or stale layer-decision schema. A runtime without `adaptive_flow`
rejects the pack instead of running a non-adaptive fallback.

## Browser target: `mob web build`

The browser runtime is the **real meerkat agent stack** compiled to wasm32 —
same agent loop, same LLM providers (Anthropic, OpenAI, Gemini), and same
streaming as CLI/RPC/REST. `mob web build` does not compile it; the command
copies the required prebuilt runtime artifacts into the browser bundle.

Prerequisites: the prebuilt meerkat-web-runtime artifacts — the wasm-bindgen
glue (`meerkat_web_runtime.js`) and its paired `meerkat_web_runtime_bg.wasm` —
produced by `wasm-pack build meerkat-web-runtime --target web` or an equivalent
wasm-bindgen pipeline. The CLI fails closed without them and never emits a
placeholder bundle. Pass either the generated output **directory** or the
`*_bg.wasm` file (the sibling `.js` glue is copied alongside it):

```bash theme={null}
rkat mob web build ./dist/release-triage.mobpack -o ./dist/release-triage-web --wasm ./meerkat-web-runtime/pkg --trust-policy permissive
```

Output is a static asset bundle. It still needs provider access through a
user-supplied key or your authenticated proxy. Serve the directory
(for example with `python3 -m http.server`) and open `index.html`:

* `index.html` - browser bootstrap page: trust-verifies the pack and initializes the WASM runtime, but does not create a mob or provide prompt/transcript UI
* `meerkat-bootstrap.js` — reusable ES module exporting `bootMobpack(opts)`; import it from your own app
* `meerkat_web_runtime.js` — the wasm-bindgen glue
* `meerkat_web_runtime_bg.wasm` — the compiled meerkat agent stack
* `mobpack.bin` — the packed mob artifact (loaded via the runtime's `init_runtime`)
* `manifest.web.toml` — derived web manifest

The generated `bootMobpack` bakes in the trust policy this bundle was built with
(`--trust-policy`); override it (and supply `trusted_signers`) for signed/strict
production deployments.

### How the WASM runtime works

The runtime uses `tokio_with_wasm` as a drop-in tokio replacement (backed by the JS event loop), `reqwest` with browser `fetch` for HTTP, and `web-time` for browser-safe timestamps. The `#[async_trait(?Send)]` pattern handles wasm32's single-threaded model.

API:

```typescript theme={null}
import { MeerkatRuntime } from "@rkat/web";
import * as wasm from "@rkat/web/wasm/meerkat_web_runtime.js";

const runtime = await MeerkatRuntime.initFromMobpack(wasm, mobpackBytes, {
  anthropicApiKey: "sk-ant-...",
  model: "claude-sonnet-4-6",
});

const session = runtime.createSession({ model: "claude-sonnet-4-6" });
const result = await session.turn("Your prompt here");
const events = session.pollEvents();
```

### Browser capabilities and limitations

**Available:** agent loop (streaming, retries), all LLM providers, sessions, JSON schema validation, budget enforcement, events, skills, MCP config types, tool/compactor/memory traits.

**Not available (browser inherent):** filesystem config loading, stdio MCP servers, shell tool, file-based persistence. Use programmatic config and in-memory storage instead.

**Not yet available (upstream blocker):** MCP protocol client over HTTP — the `rmcp` crate depends on `tokio`/`mio` which don't compile on wasm32. MCP config types and tool definitions work; actual connections to MCP servers are blocked pending rmcp wasm32 support.

## Cool web patterns

### Incident war room

Build `ops-war-room.mobpack`, publish web bundle behind internal auth, and let responders open a zero-install multi-agent workspace in-browser.

### Embedded dashboard copilot

Bundle `dashboard-copilot.mobpack` and embed it in your observability or release dashboard to summarize anomalies and propose mitigation steps in context.

## Example library

See runnable examples:

* `examples/028-mobpack-release-triage-sh` for a signed release-triage mobpack that is packed, inspected, validated, and deployed end to end
* `examples/029-web-incident-war-room-sh` for a browser-deployable SEV war room with source-controlled mobpack inputs and kickoff prompts
* `examples/030-web-dashboard-copilot-sh` for an embeddable dashboard copilot that emits a web bundle plus sample host-integration assets

## See also

* [Examples: Mobpack](/examples/mobpack)
* [Examples: WASM](/examples/wasm)
* [Mobs guide](/guides/mobs)
