* bootstrap: `garage layout show` truncates node IDs to 16 chars, but
the membership check compared against the full hex. After the first
successful join, subsequent runs no longer found the short ID in
`layout show` and re-issued `layout assign`, marking the task
changed every time. Compare against both the truncated and the full
form so a configured node stays detected. Also tag the read-only
`garage node id` / `layout show` probes with `changed_when: false`.
* provision keys: the old parser sliced `stdout_lines[1:]` to drop the
header but missed that INFO log lines and ANSI escapes can interleave
with table rows. Replace with an explicit `^GK[0-9a-fA-F]+` filter
after stripping ANSI, so probe-output noise no longer corrupts the
existing-keys set and triggers spurious `key new` calls.
* provision buckets: same class of fix — match `^[0-9a-f]{16}\s` data
rows instead of slicing `[2:]`, which broke when the table header
wasn't exactly two lines.
* provision permissions: pre-read `bucket info` for each (key, bucket)
pair and only run `bucket allow` when the current `RWO` flag set for
that key ID doesn't already match the desired permissions. Previously
`bucket allow` ran unconditionally and reported changed every play.
* `changed_when: false` on all read-only probes (`key list`, `key info`,
`bucket list`).