gloves 0.1.0

Dual-backend secrets manager for OpenClaw agents
Documentation
# Gloves Implementation and Test Plan

This plan is organized by Rust module boundaries and production-quality practices, not by implementation phases.

## Engineering Principles

- Module-first design: keep related types and behavior together.
- Test-first behavior changes: add failing tests before logic changes.
- Strong error contracts: use explicit `Result<T, GlovesError>` mapping.
- Security defaults: private file permissions, atomic writes, integrity checks.
- Deterministic CI gates: formatting, linting, tests, docs, publish dry-run.

## Domain: Types and Validation (`src/types.rs`, `src/error.rs`)

### Required behavior tests

- `secret_id_valid`
- `secret_id_empty`
- `secret_id_too_long`
- `secret_id_traversal`
- `secret_id_leading_slash`
- `secret_id_special_chars`
- `owner_serde`
- `secret_id_display`
- `agent_id_validation_and_display`
- `request_status_serde_all_variants`
- `secret_value_expose`
- `secret_value_no_debug` (`trybuild`)
- `secret_meta_roundtrip`
- `pending_request_roundtrip`

## Domain: Key Derivation (`src/agent/keys.rs`)

### Required behavior tests

- `derive_deterministic`
- `derive_different_salt`
- `derive_different_agent`
- `derive_different_vm`
- `salt_init_creates_file`
- `salt_init_idempotent`
- `salt_invalid_length_fails`
- `salt_permissions_0600`

## Domain: Agent Cryptography Backend (`src/agent/backend.rs`)

### Required behavior tests

- `encrypt_decrypt_roundtrip`
- `decrypt_wrong_key_fails`
- `decrypt_unsupported_header_fails`
- `multi_recipient_both_decrypt`
- `multi_recipient_outsider_fails`
- `encrypt_creates_age_file`
- `encrypt_no_overwrite`
- `encrypt_without_recipients_fails`
- `grant_adds_recipient`
- `ciphertext_checksum_changes_after_grant`
- `file_permissions_0600`
- `delete_missing_is_ok`
- `parse_identity_roundtrip`
- `parse_identity_invalid`

## Domain: Metadata and Registry (`src/agent/meta.rs`, `src/registry.rs`)

### Required behavior tests

- `meta_save_load_roundtrip`
- `meta_delete_missing_is_ok`
- `meta_list_ignores_non_json_files`
- `registry_register_lookup`
- `registry_reject_duplicate`
- `registry_first_agent_bootstrap`
- `registry_second_agent_with_valid_voucher_succeeds`
- `registry_voucher_required`
- `registry_rejects_unknown_voucher`
- `registry_hmac_valid`
- `registry_hmac_tampered`
- `registry_file_permissions_0600`

## Domain: Human Backend and Pending Access (`src/human/backend.rs`, `src/human/pending.rs`)

### Required behavior tests

- `get_parses_stdout`
- `get_not_found`
- `get_gpg_denied`
- `get_unknown_error_maps_crypto`
- `exists_true`
- `exists_false`
- `system_pass_executor_runs_custom_binary`
- `system_pass_executor_utf8_error`
- `system_pass_executor_default_constructs`
- `human_backend_default_constructs`
- `pending_create_persist`
- `pending_auto_expire`
- `pending_approve`
- `pending_deny`
- `pending_approve_not_found`
- `pending_deny_not_found`
- `pending_is_fulfilled_false_without_match`
- `pending_signature_tamper_fails_load`

## Domain: Secrets Router (`src/manager.rs`)

### Required behavior tests

- `set_agent_secret`
- `set_human_forbidden`
- `set_rolls_back_ciphertext_when_metadata_save_fails`
- `set_rolls_back_metadata_and_ciphertext_when_audit_fails`
- `get_routes_agent`
- `get_agent_without_identity_is_unauthorized`
- `get_routes_human`
- `get_human_without_approval_forbidden`
- `get_expired`
- `get_unauthorized`
- `get_tampered_ciphertext_fails_integrity`
- `get_with_empty_checksum_allows_legacy_metadata`
- `get_increments_access`
- `request_creates_pending`
- `grant_agent_ok`
- `grant_human_forbidden`
- `grant_by_non_creator_forbidden`
- `revoke_by_creator`
- `revoke_by_noncreator`
- `list_all`
- `approve_and_deny_request_wrappers`

## Domain: Audit and Retention (`src/audit.rs`, `src/reaper.rs`)

### Required behavior tests

- `log_writes_jsonl`
- `log_appends`
- `all_events_serialize`
- `log_file_permissions`
- `log_includes_timestamp`
- `reaps_expired`
- `keeps_valid`
- `logs_expiry_event`
- `handles_empty_dir`
- `secure_delete_zeroes`
- `secure_delete_missing_file_is_ok`

## Domain: CLI and Runtime Paths (`src/cli/mod.rs`, `src/main.rs`, `src/paths.rs`, `src/fs_secure.rs`)

### Required behavior tests

- `cli_init`
- `cli_set_generate`
- `cli_set_duplicate_secret_fails`
- `cli_set_then_get_roundtrip`
- `cli_set_from_stdin`
- `cli_set_empty_stdin_rejected`
- `cli_set_requires_input_source`
- `cli_set_rejects_generate_and_value`
- `cli_set_rejects_empty_value`
- `cli_get_redacted`
- `cli_get_raw_tty_warning`
- `cli_request`
- `cli_request_twice_uses_existing_signing_key`
- `cli_request_fails_when_pending_json_is_unreadable`
- `cli_approve_request`
- `cli_approve_invalid_uuid_fails`
- `cli_deny_request`
- `cli_list`
- `cli_revoke`
- `cli_status`
- `cli_status_defaults_to_fulfilled`
- `cli_verify`
- `cli_verify_fails_on_invalid_metadata_file`
- `secrets_paths_layout`
- `create_private_file_if_missing_does_not_overwrite`
- `write_private_file_atomic_overwrites`
- `ensure_private_dir_creates_directory`
- `private_permissions_are_restricted`

## Release Gates

Run all gates before merging or publishing:

```bash
cargo fmt --all
cargo clippy --all-targets --all-features -- -D warnings
cargo test --all-features
cargo llvm-cov --all-features --workspace --summary-only
cargo doc --no-deps
cargo publish --dry-run --locked
```

## Coverage Target

- Region coverage target: `>= 90%`
- Function coverage target: `>= 95%`
- Line coverage target: `>= 99%`