enprot 0.4.1

Engyon Protected Text (EPT) — confidentiality processor and capability ledger
# 22 — Command-style CLI

## Problem

Today every operation is a flag (`-e`, `-d`, `-s`, `-f`, `-E`) on a single
flat argument list. Multi-operation invocations read right-to-left and are
hard to scan:

```
enprot -e a -e b -d c -k a=1 -k b=2 -k c=3 file.ept
```

## Approach

Subcommands. Each operation becomes its own subcommand; shared options
(verbose, policy, casdir, etc.) live in a `CommonArgs` struct that's
`#[command(flatten)]`-ed into each subcommand.

```rust
#[derive(Parser)]
#[command(name = "enprot", version, about = "…")]
struct Cli {
    #[command(flatten)]
    common: CommonArgs,

    #[command(subcommand)]
    command: Command,
}

#[derive(Subcommand)]
enum Command {
    /// Encrypt WORD segments.
    Encrypt { words: Words, #[command(flatten)] opts: EncryptOpts, files: Vec<PathBuf> },
    /// Decrypt WORD segments.
    Decrypt { words: Words, #[command(flatten)] opts: CommonOperationArgs, files: Vec<PathBuf> },
    /// Store (unencrypted) WORD segments to CAS.
    Store  { words: Words, #[command(flatten)] opts: CommonOperationArgs, files: Vec<PathBuf> },
    /// Fetch (unencrypted) WORD segments from CAS.
    Fetch  { words: Words, #[command(flatten)] opts: CommonOperationArgs, files: Vec<PathBuf> },
    /// Encrypt and store WORD segments.
    EncryptStore { words: Words, #[command(flatten)] opts: EncryptOpts, files: Vec<PathBuf> },
}
```

### Design decisions

- **Hard cut, no flag-mode alias.** Keeping both shapes doubles the test
  matrix and confuses users. The flat-flag form is gone.
- **WORD list is positional**, not a flag. `enprot encrypt Agent_007 GEHEIM
  file.ept` is the natural spelling. Multi-value is via repetition or
  space separation.
- **`-k`/`--key` is shared.** Stays in `CommonArgs` since every operation
  can need a password.
- **Crypto knobs (pbkdf, cipher, salt, IV, etc.) move under `EncryptOpts`**
  since they're meaningless for decrypt/store/fetch. This is the OCP win:
  the surface for "things only encrypt cares about" is now scoped to one
  struct.
- **`--max-depth`, `--left-separator`, `--right-separator`** move to
  `CommonArgs` (they're parsing concerns).

### Migration

Existing test invocations:

```
enprot -e Agent_007 --pbkdf legacy -k Agent_007=password file.ept
```

become:

```
enprot encrypt Agent_007 --pbkdf legacy -k Agent_007=password file.ept
```

The README tutorial and every test in `tests/cli/*.rs` need updating.
That's a lot of mechanical edits but each is a 1-line transform.

### Backward compatibility

None. This is a hard cut. Users scripting enprot need to update. The
commit message will spell this out and the version should bump to 0.4.0
when released.

## Files

- `src/lib.rs` — full Cli rewrite.
- `src/consts.rs` — possibly add a `Words` newtype if useful.
- `tests/cli/*.rs` — update every invocation.
- `tests/tests.rs``app_main` callers in `pbkdf.rs` test need to switch
  to subcommand form.
- `README.adoc` — tutorial section rewrite.
- `CLAUDE.md` — CLI wiring section update.

## Verification

```
cargo test
cargo run -- encrypt Agent_007 --pbkdf legacy -k Agent_007=password sample/test.ept
cargo run -- --help
cargo run -- encrypt --help
```

`cargo run -- --help` lists the subcommands. `cargo run -- encrypt --help`
shows the encrypt-specific options.

## Rollback

Revert `src/lib.rs` and the test/README updates. Large but mechanical.

## Out of scope

- Shell completion generation (`clap_complete`) — could add as a follow-up.
- Interactive mode (REPL-ish) — not requested.