## v1.10.0 — 2026-06-09

Batch 3 of the "add everything" pass. Two features:

- **Resume support for `shard image` + `shard restore`.** Long streaming
  ops now write a tiny `<dst>.shardprogress` (image) or
  `<src>.restore.shardprogress` (restore) JSON sidecar every ~64 MiB,
  atomically (write-to-tmp + rename). On `--resume` shard:
  - loads the sidecar,
  - re-checks the source identity (1 MiB SHA-256 fingerprint — refuses
    if the source was swapped),
  - verifies the source size hasn't changed,
  - rebuilds the in-flight SHA-256 by re-hashing the bytes already
    written to dst (image only — restore re-verifies at the end against
    the source's `.sha256`),
  - continues from `bytes_written`.
  Refuses to re-create dst when a progress sidecar already exists unless
  `--resume` is passed. Refuses `--resume` combined with `--compress` or
  `--encrypt` (the on-disk artifact is post-transform; hash state can't
  be reconstructed mid-stream). `shard rip --resume` is **not** included
  in this version — rip's multi-mode pipeline (cdda / data / bd /
  multisession / mixed) needs per-mode handling; queued for a follow-up.
- **Persistent live USB for `shard install`.** New `--persistent SIZE`
  flag appends a `casper-rw` ext4 partition after the flashed ISO so
  Ubuntu / Debian / Linux Mint / Pop!_OS live systems retain `/home` +
  `/etc` changes across reboots. SIZE accepts sfdisk-style tokens
  (`4G`, `2GiB`, `rest`). Refuses for Fedora (use `livecd-iso-to-disk
  --overlay-size-mb` directly) and for non-live distros (Arch / NixOS)
  with friendly errors.

## v1.9.0 — 2026-06-09

Batch 2 of the "add everything" pass. Six new features:

- New: `shard partition` — GPT/MBR table create + dump via `sfdisk`. Layout
  spec is a comma-separated list of sizes (`4G,rest`; `512MiB,2GiB,rest`)
  with `rest` always last. Read mode is ungated; `--scheme/--layout` and
  `--delete-table` go through the standard auth + per-device prompt. New
  optional deps: `sfdisk`, `partprobe`.
- New: `shard clone` — stream `--src /dev/X` → `--dst /dev/Y` in one pass
  with rolling SHA-256 of source + read-back verify on destination. Avoids
  intermediate image files for big disks. Refuses when dst < src unless
  `--allow-shrink`. `--no-verify` available for trusted setups.
- New: `shard smart` — full SMART workflow on top of `smartctl --json=g`:
  attribute / NVMe-log / self-test-log dump; `--self-test short|long|
  conveyance` scheduling; `--abort`; `--snapshot` to persist raw JSON
  under `~/.local/share/shard/smart/`; `--diff` between the two latest
  snapshots (power-on hours, temperature, NVMe wear, ATA raw deltas).
- New: `shard benchmark --write` — destructive 256 MiB write sample
  (oflag=direct + conv=fsync). Gated by `--i-am-authorized` + per-device
  prompt. Useful for outing cheap SD cards that read fast and write slow.
- TUI: new **History pane** — audit-log filtered to the currently-
  selected device. Press `h` to open; Tab cycle now goes Devices → Log
  → History → Doctor.
- TUI: **automatic refresh on hotplug** — a background `udevadm monitor`
  watcher pulses an internal flag on any block-device add / remove /
  change, and the event loop refreshes the device list within ~250 ms.
  Suppressed while a modal or running op is in-flight. Optional dep
  `udevadm` (the suite already pulls it in).
- New: `shard fs-info [--fs SLUG]` — print the OS-compatibility table
  for one filesystem (or all 18 supported types). Per FS: read/write
  status on Linux, macOS, Windows, Android, iOS, *BSD; max file size;
  max volume size; "good for" one-liner. The same readout is now
  printed by `shard format` immediately before the destructive-confirm
  prompt, so the operator sees *who can read this volume afterwards*
  before they commit.

## v1.8.0 — 2026-06-09

- New: `shard wipefs` — metadata-only signature wipe (filesystem / GPT /
  LUKS / RAID magics). Much faster than `erase --mode quick` when you just
  need the kernel to stop recognising stale signatures before a new
  partition / format / flash. `--list-only` runs `wipefs --no-act` (read-
  only inventory of what *would* be wiped). New optional dep: `wipefs`.
- New: **Certificate of destruction** — on every successful `shard erase`,
  shard now writes a per-erase JSON + plain-text receipt + SHA-256 sidecar
  to `~/.local/share/shard/certs/`. Captures device metadata, mode,
  start/end timestamps, operator, hostname, and the audit-log link. Suits
  HIPAA / GDPR Article 17 / PCI-DSS 9.8 disposal evidence. Disable with
  `--no-cert`; override directory with `--cert-dir DIR`.
- New: **Audit-log HMAC chain** — every audit entry from v1.8+ is HMAC-
  SHA256 signed with a per-host 32-byte key (auto-generated at
  `~/.local/share/shard/.audit-key`, mode 0600). Each entry chains from
  the previous one's HMAC, so tampering with any past line breaks every
  later HMAC. Pre-v1.8 'legacy' entries (no `seq`/`prev_hmac`/`hmac`
  fields) remain in the file and are tolerated by readers.
- New: `shard log --verify` — walks the chain, reports any HMAC mismatch
  / prev_hmac break / seq jump. Exit 0 if intact, 3 on any break.
- TUI: **Output modal is now scrollable** — j/k or ↑/↓ scroll one line;
  Space / PgDn page down; PgUp page up; g / Home jump to top; G / End
  jump to bottom; Esc / Enter / q close. Title bar shows current line +
  total. The Help modal documents the new keys.
- Drive-by fix: `Config::audit_log_path()` returned `audit.log`, but every
  other call site referenced `audit.jsonl`. Standardised on `audit.jsonl`
  (file format is JSONL). Operators with an existing `audit.log` should
  rename it once before upgrading; the chain start picks up from the last
  parseable line.

## v1.7.0 — 2026-06-09

- New: `shard install` — download a Linux ISO from a **curated catalog**
  baked into the binary, verify SHA-256 against a pinned hash, then flash
  to a USB device. URLs point at each distro's official CDN; shard does
  not host ISOs. Ships with entries for Ubuntu LTS, Debian Live, Fedora
  Workstation, Linux Mint, and Pop!_OS — operators can add more via a
  user override.
- Trust model: hashes ship as `null`; first use of each distro requires
  `shard install --refresh-hashes <slug>` to download once, compute
  SHA-256, and pin it to `~/.config/shard/distros.json`. Subsequent
  installs verify against the pin and refuse on mismatch. There is no
  trust-on-first-flash — operator pins before the device is touched.
- ISO cache lives at `~/.cache/shard/iso/<slug>.iso`; cached copies are
  re-verified on every use and re-downloaded on hash mismatch.
- New optional dep: `curl` (surfaced in `shard doctor`).
- Read-only sub-flows: `shard install --list` prints the catalog with
  pinned/unpinned status; `shard install --refresh-hashes` (no slugs)
  pins all entries in one pass.

## v1.6.0 — 2026-06-09

- `shard tui` now shows a live **progress modal** for every action — erase,
  format, flash, restore, image, repair, info, benchmark, locate. The
  subprocess is spawned non-blocking; reader threads stream stdout+stderr
  through a parser that picks up `dd status=progress` byte/rate lines and
  our own `pass i/N` markers (multi-pass overwrite). The modal renders a
  Gauge + elapsed / ETA / throughput / pass stats + a live tail of the
  underlying tool output.
- ETA is computed when total size + throughput are known (erase quick/
  thorough/dod, image, flash, restore). Ops without a byte stream
  (discard / secure / sanitize / mkfs.*) fall back to an indeterminate
  sweep with elapsed time so the operator can tell the op is still alive.
- `[Esc]` / `[q]` from the progress modal requests an abort (sends SIGKILL
  to the child `shard` process). Output modal still appears once the
  subprocess exits, so the audit trail is preserved.

## v1.4.0 — 2026-06-07

- New: `shard tui` — full-screen interactive terminal UI (ratatui + crossterm).
  Three-pane layout (Devices / Detail / Log+Doctor) with an action menu per
  selected device. Read-only actions (info, benchmark, locate, image, mount)
  run inline and capture stdout into an output panel. Destructive actions
  (erase, format, flash, repair, restore) ALWAYS open a typed-confirm modal:
  the operator must type the full /dev/<path> exactly before the action
  executes. `D` toggles a dry-run mode that previews destructive ops without
  writing. Authorization is supplied by the modal itself — no separate
  `--i-am-authorized` is required while in the TUI.
- The TUI re-execs `shard` itself for action dispatch so dry-run, the audit
  log, and the same gating apply uniformly to CLI and TUI invocations.

## v1.3.0 — 2026-06-07

- New: `--full` global flag — prints extended help with worked examples for one
  subcommand (`shard <CMD> --full`) or the whole-tool cheat-sheet (`shard --full`).
  Every subcommand also gains a richer `long_about` (Touches / Produces / Gates +
  examples) on plain `--help`.
- `--device <PATH>` help now spells out the expected form (`/dev/sda`, NOT `sda`)
  on every subcommand that takes one.
- `shard format` now supports the full common Linux + cross-platform + legacy
  set: ext2, ext3, ext4, xfs, btrfs, f2fs, exfat, fat12, fat16, fat32, ntfs,
  hfsplus, udf, jfs (AIX), minix (v3), bfs (SCO), swap, and luks-ext4. New
  optional deps surfaced in `shard doctor`: mkfs.ext2/ext3/xfs/btrfs/f2fs/ntfs/
  hfsplus/udf/jfs/minix/bfs and mkswap.
- `shard format` rejects unsupported targets (apfs, ufs, hfs, zfs, erofs,
  squashfs, ubifs/jffs2/yaffs, android, ios, harmonyos) with a friendly error
  that points at the right answer.
- `shard mount` now auto-routes APFS partitions through `apfs-fuse` (read-only)
  and NTFS partitions through `ntfs-3g` when available, falling back to plain
  `mount` for kernel-native filesystems. F2FS / HFS+ / HFS+ classic / UDF
  / EROFS / SquashFS are auto-detected via lsblk's reported fstype.

## v1.2.0 — 2026-06-04

- New: `shard verify --image PATH` — recompute SHA-256 and compare to the
  `.sha256` sidecar (long-term bitrot check).
- New: `shard restore --image PATH --device DEV` — write an image back to a
  device. Sidecar is verified before the write and the device is hashed-back
  afterward, mirroring `shard flash`.
- New: `shard mount --image PATH [--mount-at DIR]` — losetup --partscan,
  enumerate partitions, optionally read-only mount the first filesystem-bearing
  partition. `shard mount --detach /dev/loopN` releases it.
- New: `shard watch` — stream block-device hotplug events from
  `udevadm monitor` (re-implements the v0.1.0 Python feature).
- New: `shard locate --device DEV [--seconds N]` — pulse the activity LED by
  issuing periodic small reads (works on anything with an LED, no SES/vendor API).
- New: `shard log [--since 7d] [--action erase] [--device /dev/sdb]` — query
  and filter the JSONL audit log, with `--output json` for raw passthrough.
- New: `shard erase --mode secure` — NVMe `nvme format -s 1` or SATA
  `hdparm --security-erase`. Refuses on frozen SATA drives with a thaw hint.
  Refuses on USB-attached devices (firmware command set isn't reachable).
- New: `shard image/rip --compress` — pipe through `zstd -T0` (extension `.zst`).
- New: `shard image/rip --encrypt` — pipe through `age -p` (extension `.age`).
  Composable: `--compress --encrypt` produces `.img.zst.age`. The SHA-256
  sidecar covers the final on-disk artifact.
- `device::lookup` now searches partitions too — `/dev/sda1` resolves the
  same way `/dev/sda` does.
- `losetup`, `mount`, `zstd`, `age`, `hdparm`, plus `nvme`/`udevadm` are now
  surfaced in `shard doctor` as optional dependencies of the new features.

## v1.1.0 — 2026-06-04

- Fix: USB-C external SSD/NVMe enclosures (Samsung, JMicron/ASMedia bridges, etc.)
  were silently dropped in laptop mode because the kernel reports `rm=0` for
  them. The laptop-mode filter now keys on `transport=usb` alone — the
  root-device check remains the safety net. Regression test added.
- New: `shard image --device <dev> [--out PATH]` — clone a disk / USB / SD card
  to a raw `.img` file with a `sha256sum`-compatible sidecar, computed in a
  single streaming pass. Read-only on the source; no `--i-am-authorized` needed.
- New: `shard rip --device <dev> [--out PATH] [--rescue]` — rip a CD / DVD to
  `.iso` + sidecar (2 KiB block size). `--rescue` invokes `ddrescue` for
  scratched discs.
- Both commands default the output to the current working directory with an
  auto-generated `shard-<vendor>-<model>-<serial>-<timestamp>` filename.
  `--out PATH` accepts either a directory (writes inside with the auto-name)
  or an explicit file path. Existing paths are never silently clobbered.
- `ddrescue` added as an optional dependency in `shard doctor`.

## v0.1.1 — 2026-05-22

- Added `--tui` as an accepted no-op flag for API consistency (shard is interactive by default).

## v0.1.0 — 2026-04-10

Initial release.

- Dual mode: laptop (USB focus, port-aware) and server (by-id, SMART-gated)
- Auto-detect mode via battery presence
- SMART health assessment: OK, DEGRADED, CRITICAL, N/A classification
- NVMe smart-log support via nvme-cli
- Non-destructive read-test fallback for USB flash devices
- Multi-step repair: fsck, badblocks write pass, SMART recheck
- Secure erase: quick (1 pass) and thorough (3 passes)
- Format: LUKS+ext4, ext4, exFAT, FAT32 with ownership prompts
- ISO flash with SHA256 pre/post verification
- Filesystem detection: 16 types including APFS, HFS+, LUKS, CoreStorage
- USB port identification with bus/port/speed topology
- Background file inventory with category breakdown
- Speed benchmark with wall-clock time estimates
- Hotplug watcher for real-time device add/remove notifications
- Panic wipe: --panic flag or !DOOM keystroke sequence
- Condemned device banner for physical destruction records
- JSONL audit log with structured operation records
- Dry-run mode for safe command preview
- Device LED pulse identification (laptop mode)
- Dependency checker with distro-specific install commands
- Zero third-party Python dependencies — stdlib only
