# crypto-bin Specification ## Purpose TBD - created by archiving change crypto-completion. Update Purpose after archive. ## Requirements ### Requirement: hash-password CLI hash mode The package SHALL ship a `suaveplan-hash-password` bin that, when invoked with `--password ` and no `--verify`, hashes the password using the requested algorithm (default `argon2id`, opt-in `--algo blake2b`) and writes the resulting stored-hash string to stdout, exiting with code 0. The CLI SHALL route through `@suaveplan/cli`'s arg parser (so `--help` works automatically) and SHALL NEVER call `process.exit` directly — it SHALL use `cli.exit(code)` to keep test harness compatibility. #### Scenario: argon2id mode prints stored hash - **WHEN** `suaveplan-hash-password --password "correct horse battery staple"` is invoked - **THEN** stdout contains a string starting with `"$argon2id$"` AND the exit code is 0 #### Scenario: blake2b mode prints stored hash - **WHEN** `suaveplan-hash-password --password "..." --algo blake2b` is invoked - **THEN** stdout contains a string starting with `"$blake2b$"` AND the exit code is 0 **Verified by:** `packages/crypto/crypto-bin/src/hash-password/hash-password.test.ts::"argon2id mode writes a $argon2id$-prefixed hash to stdout and exits 0"` AND `packages/crypto/crypto-bin/src/hash-password/hash-password.test.ts::"blake2b mode writes a $blake2b$-prefixed hash to stdout and exits 0"` --- ### Requirement: hash-password CLI verify mode When invoked with `--password ` and `--verify `, the bin SHALL detect the algorithm from the stored hash's prefix, run the matching verify function (`verifyPasswordArgon2id` or `verifyPasswordBlake2b`), exit with code 0 on match and code 1 on mismatch. The bin SHALL NOT print anything to stdout in verify mode (so the exit code is the only signal — suitable for use in shell pipelines). #### Scenario: matching password exits 0 - **WHEN** the stored hash and the password agree - **THEN** the exit code is 0 AND stdout is empty #### Scenario: non-matching password exits 1 - **WHEN** the stored hash and the password disagree - **THEN** the exit code is 1 AND stdout is empty **Verified by:** `packages/crypto/crypto-bin/src/hash-password/hash-password.test.ts::"verify mode exits 0 when password matches stored hash"` AND `packages/crypto/crypto-bin/src/hash-password/hash-password.test.ts::"verify mode exits 1 when password does not match stored hash"` --- ### Requirement: hash-password CLI argument validation The bin SHALL reject malformed invocations (missing `--password`, unknown `--algo`, malformed `--verify` value) with a non-zero exit code and a `SuaveplanError` whose code is one of `CRYPTO.HASH_PASSWORD_CLI_BAD_ARGS`, `CRYPTO.HASH_PASSWORD_CLI_UNKNOWN_ALGO`, or `CRYPTO.HASH_PASSWORD_CLI_VERIFY_FAILED`. The error message SHALL be human-readable and SHALL be printed to stderr (not stdout, so it does not contaminate pipe output). #### Scenario: missing --password rejected - **WHEN** `suaveplan-hash-password` is invoked with no `--password` - **THEN** the exit code is non-zero AND stderr mentions `--password` AND the underlying error code is `CRYPTO.HASH_PASSWORD_CLI_BAD_ARGS` #### Scenario: unknown algorithm rejected - **WHEN** `suaveplan-hash-password --password pw --algo bcrypt` is invoked - **THEN** the exit code is non-zero AND the underlying error code is `CRYPTO.HASH_PASSWORD_CLI_UNKNOWN_ALGO` AND `context.algo === "bcrypt"` **Verified by:** `packages/crypto/crypto-bin/src/hash-password/hash-password.spec-conformance.test.ts::"missing --password emits HASH_PASSWORD_CLI_BAD_ARGS"` AND `packages/crypto/crypto-bin/src/hash-password/hash-password.spec-conformance.test.ts::"unknown --algo emits HASH_PASSWORD_CLI_UNKNOWN_ALGO"`