# move — guide
> **Class:** `guide` · audience: an operator receiving a bundle on the secure side. The *what* is
> in [`move-design.md`](move-design.md).
## The receive gate (do this before touching anything)
```rust
use skidbladnir::{archive::TarZstd, fetch};
let eng = TarZstd::new();
// simplest: verify (manifest root + every entry) and get a handle, or bail:
let bundle = fetch::fetch_and_verify(&bundle_path, &eng)?; // fetch.rs:74
```
To also check an out-of-band whole-file SHA (handed to you separately from the bundle — e.g. read
aloud, or on a second medium):
```rust
let report = fetch::verify_on_receipt(&bundle_path, &eng, Some(expected_sha))?;
assert!(report.is_ok(), "receipt failed: {report:?}");
// report.bundle_hash_ok / manifest_root_ok / bad_entries pinpoint what went wrong
```
If verification fails, **stop** — do not unpack. A non-empty `bad_entries`, a false
`manifest_root_ok`, or a false `bundle_hash_ok` each means the bundle is not what was packed.
## Detect the OS and prepare it
```rust
use skidbladnir::platform::{Platform, specialize, unpack};
let p = Platform::detect(); // reads /etc/os-release
let actions = specialize(p, /* disable_selinux */ true)?; // e.g. ["selinux:permissive"] on RHEL
```
`specialize` only touches SELinux on RHEL-family targets; on Debian/Ubuntu it is a no-op. The
toggle is best-effort and non-fatal.
## Unpack into the software dir
```rust
unpack(&eng, &bundle_path, &software_dir)?; // thin wrapper over Archive::extract_all
```
For a real product install (dirs, service, identity, ordered start) use the `install` lifecycle
instead of raw `unpack` — see [`install-guide.md`](install-guide.md).
## Gotchas
- There is **no** network transfer step — Skidbladnir assumes the bundle already sits at a local
path. How it got there (USB, diode, courier) is your problem, by design.
- The out-of-band SHA is optional but recommended: it catches corruption the manifest cannot
self-attest (the manifest is only as trustworthy as the bundle it shipped with).