# Recipient policies and selective reencryption `RecipientPolicyManager` implements `pass init` inside `crates/storage`. It accepts the storage-owned `InitRequest`, so root initialization and `--path` / `-p` initialization share the same validated relative-path rules as every other repository operation. One empty identity removes the policy at that exact directory; any other identity list is written one item per line with a final newline, matching upstream `pass`. ## Hierarchy An entry inherits the nearest `.gpg-id` in its directory or an ancestor. Nested files override their parent for the complete nested subtree. Exact fingerprints, key IDs, and user IDs are resolved by `KeyStore`; comments, whitespace, duplicates, missing identities, and ambiguous identities use the same rules as encryption elsewhere in storage. Changing a policy considers only entries below that directory which are not shielded by a deeper override. Removing an override makes those entries inherit the nearest policy above it. Removal is rejected before mutation if an affected entry would have no policy. Existing public-key session packets are compared to the resolved certificate set, so entries already encrypted for exactly the requested recipients are not needlessly rewritten. As upstream does, removing `.gpg-id` does not remove a pre-existing detached `.gpg-id.sig`; without a configured signing-key policy the orphan is ignored. Reinitializing with signing enabled replaces it. ## Authentication When `PASSWORD_STORE_SIGNING_KEY` behavior is configured, `SigningPolicy` contains the key used to create a detached signature and the explicit set of trusted primary fingerprints. A new `.gpg-id` is signed and immediately verified against that set before filesystem mutation. Inherited policies must have a signature which verifies against the same trust set. Missing, malformed, untrusted, and cryptographically invalid signatures are distinct pre-mutation failures. ## Transaction and Git boundary Resolution, signature work, decryption, and replacement encryption all finish in memory before the first repository write. Every affected entry retains its original encrypted bytes. Repository writes use private, synced temporary files and atomic per-file replacement. If any write or the storage commit hook fails, the policy, signature, and every entry are restored in reverse order; new empty policy directories are removed. A rollback failure is surfaced separately from the original operation error. `PolicyCommitter` is the integration boundary for the embedded Git engine. It receives the exact changed paths and compatible commit intent after repository bytes have been installed. It is called once for a real change, never for a no-op, and must restore any staging state before returning an error. The policy manager then restores repository bytes. `NoGitCommitter` represents a path not contained in a Git work tree; it is not used for a discovered repository. The embedded Git implementation owns concrete staging and commits, while this module owns the all-or-nothing storage mutation contract it invokes.