# Offline and restricted-network operation
## Goal
Run installs, asks, and replays on a host with no (or allow-listed)
network access, using a bundle prepared in advance on a connected machine.
## Scope
Component `law` CLI, tool `0.1.1`. Scenario: a closed host where package
registries and release servers are unreachable; all artifacts arrive by
removable media or a one-way drop. Names, paths, and sizes below are
synthetic created-examples.
## Applies to
| Branch | Coverage in this article |
|---|---|
| MCP + `law serve` | the offline bundle procedure feeds both servers; serve worlds travel as world directories (or bundles restored to directories), MCP slices as pinned profiles |
## Prerequisites
- A connected staging machine with the same pinned `law` version as the
target (check with `law version --json` on both).
- The full dependency closure of the project (`law.toml` + `law.lock`)
resolved on the staging machine.
- Write-once transfer media (created-example: `/mnt/drop/`).
## Steps
1. On the staging machine, resolve and freeze the world:
`law install --project
` (connected), then
`law test` over the `law.lock` world to confirm the closure is green.
2. Build the portable bundle (real command):
`law pack --project --out /mnt/drop/world-2026-10-03.arxo`
(real flags: `--contents full|source`, `--deps closure|pins`,
`--codec zstd|deflate`, `--zstd-level 1..19`, `--timings`,
`--no-tests`, `--json`). Prefer `--deps closure` so the bundle is
self-sufficient; the container carries packages with their
operations' inputs, identical files stored once.
3. Sign the bundle if your policy requires it (real):
`law sign /mnt/drop/world-2026-10-03.arxo --key
--role publisher`.
4. Transfer the `.arxo` file (and, for first provisioning, the `law`
release archive + `.sha256`) to the closed host.
5. On the closed host, verify before use (real):
`law inspect world-2026-10-03.arxo --verify --trust --files`.
Then either `law unpack world-2026-10-03.arxo --out ` or execute
straight from the container (`law ask …`,
`law test …` — real, no unpacking needed).
6. For project-form installs on the closed host, use the one offline
flag that exists (real): `law install --offline`. Confirm no other
package command is in your runbook (see Limits below).
7. Serve locally as usual (real):
`law serve --world --journal --host 127.0.0.1 --port 8480`
(real defaults: host `127.0.0.1`, port `8480`).
## Expected result
- `law inspect --verify` exits `0` with `integrity` and `signature`
lines matching the release record.
- `law test ` and `law ask …` exit `0` with no
network access on the host.
- `GET /healthz` and `GET /readyz` (real endpoints; readyz returns `200`
after all workers warm up) answer on the local port.
## Result check
- Disconnect the staging check: run the full ask/replay set with the
network interface down (or in a network namespace without a route) and
confirm exit `0` and unchanged `resultHash` values.
- Egress verification (operator-policy-example): capture traffic during
the run (`tcpdump`/firewall counters — created-example tooling, not
tool behavior) and confirm zero non-loopback connections; any egress
is a finding, not background noise.
## Failures and diagnostics
- `law add` / `law update` attempted offline: these subcommands have no
`--offline` flag (implementation limit, stated in `law --help`): they
must read registry descriptors to build the closure. Prepare the
closure on the connected machine instead.
- `law install --offline` failing on a missing descriptor: the bundle or
project cache is incomplete; re-run connected `law install` on staging
and re-pack with `--deps closure`.
- `no signature from a --trust or trustedKeys key`: the trust set is
non-empty but no signature matches it. Check both sides against
the independent operator trust record before touching either:
unsigned bundle, different publisher, wrong trust set, or wrong
release are all possible — a missing key file in transit is only
one of them. Never bend the trusted keys to fit the artifact you
received; resolve which side is wrong first (see
[Install and trust artifacts](/operate/install-trust-artifacts/)).
- Stale calendars/resources: the release artifact embeds `resources`
(real `law pack` content); a bundle built last quarter answers with
last quarter's resources. Re-pack when the normative inputs change.
## Support boundaries
- Supported (tool behavior): `--offline` on `install` only; container
execution without unpacking; hash/signature verification of bundles.
- Implementation limit: dependency resolution (`add`, `update`) always
needs registry descriptors; there is no offline closure solver.
- Reference setting: media paths, ports, and capture tooling here are
created-examples. "Isolated" in this article means only "no
non-loopback traffic observed during the check" — it says nothing
about side channels, media hygiene, or host hardening.
## Next step
Record the bundle filename, its hashes, and the trusted key ids in the
change log; for version moves, continue with
[Upgrades and compatibility](/operate/upgrades-compatibility/).