Raw key length not validated at store creation (Low)
src/store.ts:30, resolveKey
A { type: 'raw', key } of the wrong length is accepted; createEncryptedStore resolves "successfully" and the store is unusable — every set/get later throws INVALID_KEY. Validate the 32-byte length up front so the failure is immediate and clear.
- Multi-key writes are non-atomic with no consistency guarantee (Low–Medium for remote adapters)
src/store.ts:87-88 (body then meta), 115-116 (delete)
A crash or network failure between the two adapter.set calls leaves an orphaned body or a meta pointing at a stale body. set also has a read-modify-write TOCTOU (getMeta → write) so concurrent writes to the same id race. Acceptable for a v0 local store, but on Dropbox/CouchDB partial failures are routine — worth documenting as a known limitation, and ideally writing body-before-meta is already the safer order (meta is the "index"), so at least note that list() tolerates a missing body (it does — getMeta null-check).
Minor / robustness
Raw key length not validated at store creation (Low)
src/store.ts:30, resolveKey
A { type: 'raw', key } of the wrong length is accepted; createEncryptedStore resolves "successfully" and the store is unusable — every set/get later throws INVALID_KEY. Validate the 32-byte length up front so the failure is immediate and clear.
src/store.ts:87-88 (body then meta), 115-116 (delete)
A crash or network failure between the two adapter.set calls leaves an orphaned body or a meta pointing at a stale body. set also has a read-modify-write TOCTOU (getMeta → write) so concurrent writes to the same id race. Acceptable for a v0 local store, but on Dropbox/CouchDB partial failures are routine — worth documenting as a known limitation, and ideally writing body-before-meta is already the safer order (meta is the "index"), so at least note that list() tolerates a missing body (it does — getMeta null-check).
Minor / robustness