Files
IronStorage/docs/cli-parity.md

92 lines
5.9 KiB
Markdown

# CLI parity and executable audit
The `ironstorage` binary is a presentation and interaction adapter over
`crates/storage`. The compatibility target is password-store 1.7.4 at
`1078f2514d579178d5df7042c6a790e9c9b731ad` and pass-otp 1.2.0 at
`1e9d10ca75ae1a8672a7f192809713463657778e`. The checked-in `behavior.toml`
catalog contains 108 original, data-only cases. A contract test submits every
case to the Rust parser, while domain and CLI workflow tests exercise the
corresponding storage effects.
## Command matrix
| Upstream surface | IronStorage command | Rust owner and evidence |
| --- | --- | --- |
| default/list, `show`, `ls`, `list` | same, including implicit entry dispatch, line selection, clipboard and QR | `read`, `presentation`; command-contract, read-domain, presentation and CLI tests |
| `find`, `search`, `grep` | same aliases; supported grep flags are explicit | `read`; compatibility catalog, read-domain and complete CLI workflow tests |
| `init -p/--path` | same, including removal through an empty identity | `recipient`; recipient-policy and complete CLI workflow tests |
| `insert`, `add` | hidden-confirmed, echoed and multiline input, force and confirmation | `write`; write-domain and complete CLI workflow tests |
| `edit` | same logical edit session through the configured/default editor | `write`; editor-adapter, write-domain and complete CLI workflow tests |
| `generate` | length, no-symbols, force, in-place, clipboard and QR | `generate`; generation and CLI presentation tests |
| `rm`, `remove`, `delete` | force and recursive behavior | `mutation`; tree-mutation and complete CLI workflow tests |
| `mv`, `rename`, `cp`, `copy` | same aliases, destination and overwrite behavior | `mutation`; tree-mutation and complete CLI workflow tests |
| KeePass KDBX import | `import-kdbx [--key-file PATH] [--quick-add] SOURCE`; additive nested import with stable multiline fields | `kdbx`; KDBX compatibility and command-contract tests |
| `git` | `init`, `status`, `log`, helper-free decrypted `diff`, `add`, `commit`, `remote`, safe local `config`, `fetch`, `pull`, `push`, `sync` | `git`; embedded Git, smart-HTTP and complete CLI workflow tests |
| pass-otp default/code/show | `otp ENTRY`, `otp code`, `otp show`, clipboard | `otp`; RFC, fixture and CLI tests |
| pass-otp insert/add/append | URI or secret input and issuer/account derivation | `otp`; fixture, transaction and CLI tests |
| pass-otp uri/validate/help/version | terminal, clipboard, QR and the pinned upstream version string | `otp`, `presentation`, `command`; fixture and CLI tests |
| help/version | command, `-h`/`--help`, `-V`/`--version` forms | `command`; contract and stream/exit-code tests |
`ironstorage completion SHELL` generates Bash, Elvish, Fish, PowerShell or Zsh
completion source in process with `clap_complete`. It writes the script to
standard output and neither searches for nor invokes a shell or completion
helper.
## Deliberate boundaries
Upstream extension discovery executes files named `pass-*`. IronStorage does
not execute extensions; the first-party OTP surface is built in and typed.
Upstream `pass git` forwards arbitrary arguments to the Git executable.
IronStorage instead exposes the documented embedded workflows in the matrix.
Arbitrary passthrough such as `rebase`, `reflog`, hooks, filters, credential
helpers and helper transports is rejected. This is the only compatibility gap
in the first-party command surface and follows directly from the no-process
rule.
The sole runtime process boundary is `apps/cli/src/editor.rs`. It launches the
resolved editor program directly with parsed arguments and the private edit
file path; it never invokes a shell. A missing configured/default editor is a
typed configuration error printed on standard error, the entry is unchanged,
and the command fails. Editor failure, cancellation, oversized output and
cleanup failure are likewise typed and leave no committed mutation.
All prompts and errors use standard error. Trees, plaintext explicitly
requested for terminal display, Git reports, help, versions and completion
scripts use standard output. Clipboard and QR paths do not copy their secret
payload back to standard output. Parse and ordinary operation errors return 1,
configuration errors 78, unavailable operating-system services 69, and
success returns 0.
## Compatibility and security evidence
The compatibility fixtures contain GnuPG-produced armored and binary keys,
GPG-encrypted entries, root/nested/multiple/signed `.gpg-id` policies,
pass-otp URIs, and valid loose-object Git repositories. Tests independently
decrypt and authenticate every entry, verify recipient signatures and Git
objects, round-trip OTP URIs, and exercise automatic commits. No compatibility
test requires an upstream executable at runtime.
The executable audit checks project Rust sources for process construction and
permits it only in the editor adapter. Every project crate forbids unsafe Rust.
Git repository configuration rejects executable helpers and all non-HTTPS,
credential-bearing or rewritten remote forms before transport. Error and debug
models redact secret bytes; CLI presentation tests assert clipboard, QR, OTP
and generated values do not appear on unintended streams.
The activated dependency graph was reviewed with `cargo tree -e features` and
`cargo metadata --locked`. Gix default features are disabled and only the
embedded index, merge, revision, tree editing and Rustls smart-HTTP features
are selected. Platform secret-store implementations may compile operating-
system IPC/runtime support, but IronStorage never calls dependency APIs that
spawn a helper. Direct dependency licenses and the remaining project-license
release decision are recorded in `DEPENDENCIES.md`.
Run the executable gate from the workspace root:
```sh
cargo fmt --all -- --check
RUSTFLAGS="-D warnings" cargo check --workspace --all-targets
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace
```