# `Hyper.Node.Reaper.Plan`
[🔗](https://github.com/harmont-dev/hyper/blob/main/lib/hyper/node/reaper/plan.ex#L1)

Pure reap-decision core for `Hyper.Node.Reaper`. No I/O. Every safety invariant
is a property of these functions: a live vm_id is never a candidate, only an
orphan seen on two consecutive ticks is reaped, and only `hyper-rw-*` dm names
yield candidates (so `hyper-thinpool` / `hyper-img-*` can never be reaped).

# `confirm`

```elixir
@spec confirm(MapSet.t(String.t()), MapSet.t(String.t())) ::
  {MapSet.t(String.t()), MapSet.t(String.t())}
```

Two-strike grace: reap only ids that were also orphans last tick. Returns {to_reap, next_last}.

# `orphans`

```elixir
@spec orphans(MapSet.t(String.t()), [String.t()], [String.t()], [String.t()]) ::
  MapSet.t(String.t())
```

Candidate orphans this tick: (cgroup leaves ∪ rw vm_ids ∪ netns names) minus
the live set. `netns_names` are the leaf names of `/var/run/netns/*` — a VM's
netns is named exactly its vm_id (see `Hyper.SuidHelper.Network`), so it folds
into the same union/difference as the other two sources and is subject to the
same two-strike `confirm/2` grace before `Hyper.Node.Reaper` ever reaps it.

# `rw_ids`

```elixir
@spec rw_ids([String.t()]) :: [String.t()]
```

vm_ids of orphan rw-volumes from raw `dmsetup ls` names (only `hyper-rw-*`).

---

*Consult [api-reference.md](api-reference.md) for complete listing*
