style: capitalize "Relicario" in prose / UI / CLI help
Brand name uses capital R in user-facing text — extension UI strings, CLI clap help / descriptions / error prose, markdown docs. Lowercase preserved for the binary command, crate names, npm package, file paths, env vars, and code identifiers. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
# relicario import / export — design
|
||||
# Relicario import / export — design
|
||||
|
||||
Date: 2026-04-27
|
||||
Status: design (not yet implemented)
|
||||
Scope: backup / restore (round-trippable to relicario itself) + LastPass CSV import. Migration **out** to other tools is explicitly out of scope.
|
||||
Scope: backup / restore (round-trippable to Relicario itself) + LastPass CSV import. Migration **out** to other tools is explicitly out of scope.
|
||||
|
||||
## Motivation
|
||||
|
||||
Self-hosting a password vault without a backup story is unacceptable for production use. Today, a relicario user has no way to:
|
||||
Self-hosting a password vault without a backup story is unacceptable for production use. Today, a Relicario user has no way to:
|
||||
1. **Snapshot** their vault for disaster recovery (git remote going away, repo corruption, account loss).
|
||||
2. **Onboard** from an existing manager — there's no migration path for a user with credentials in another tool.
|
||||
|
||||
@@ -18,13 +18,13 @@ The following choices were brainstormed and approved before this spec was writte
|
||||
|
||||
| # | Decision |
|
||||
|---|---|
|
||||
| D1 | Two features, one spec: backup/restore round-trippable to relicario, plus a LastPass CSV importer. Migration out is out of scope. |
|
||||
| D1 | Two features, one spec: backup/restore round-trippable to Relicario, plus a LastPass CSV importer. Migration out is out of scope. |
|
||||
| D2 | Backup file format: single-file `.relbak` container. Magic header + version + salt + nonce + AEAD-encrypted, zstd-compressed JSON envelope with base64'd binary blobs. |
|
||||
| D3 | AEAD: XChaCha20-Poly1305 (same primitive used for vault items, but the backup format uses its own envelope with magic header + version byte; it does **not** reuse the `crypto.rs` `encrypt`/`decrypt` helpers, which assume the vault-master-key format). KDF: Argon2id with the same parameters as v1 of the live vault (m=64MiB, t=3, p=4) — but the params are tied to **backup format version**, not read from the vault's `params.json`. |
|
||||
| D4 | Backup passphrase is independent of the vault passphrase. User picks one at export; user types it at restore. Reusing the vault passphrase is allowed but not auto-filled. |
|
||||
| D5 | Reference image inclusion is optional. `--include-image` flag (CLI) / checkbox (UI). When included, the image is base64'd into the encrypted envelope — never in the clear inside the file. |
|
||||
| D6 | Git history (`.git/`) is included **by default**. `--no-history` opt-out for users who want a smaller file at the cost of audit trail and remote URL. |
|
||||
| D7 | Restore semantics: refuse if the target directory already contains a relicario vault. Restore is a fresh round-trip operation, not a merge. |
|
||||
| D7 | Restore semantics: refuse if the target directory already contains a Relicario vault. Restore is a fresh round-trip operation, not a merge. |
|
||||
| D8 | Backup passphrase strength: zxcvbn score ≥ 3, same gate as `init`. Backup is single-factor (one passphrase decrypts the container), so it must be at least as strong as a vault factor. |
|
||||
| D9 | The user is responsible for deleting the backup file after restore is verified. The encryption protects it in transit / at rest while it exists; it is not a defense against forensic recovery of deleted copies. Documented in CLI help text and the extension UI. |
|
||||
| D10 | LastPass import: parse the standard LastPass CSV (`url,username,password,totp,extra,name,grouping,fav`). Logins → `Login` items (with embedded TOTP if present); rows with `url == http://sn` → `SecureNote`; structured LastPass notes (cards, SSH keys, addresses) are **not** auto-parsed — they fall through as `SecureNote` with `extra` as the body. |
|
||||
@@ -215,7 +215,7 @@ Future format v2 may change these; v1 readers will see `version != 0x01` and pro
|
||||
|
||||
## LastPass field mapping
|
||||
|
||||
| LastPass column | relicario destination | Notes |
|
||||
| LastPass column | Relicario destination | Notes |
|
||||
|---|---|---|
|
||||
| `name` | `Item.title` | Required; row skipped with warning if missing |
|
||||
| `grouping` | `Item.group` | `None` if empty |
|
||||
@@ -246,11 +246,11 @@ Atomicity: output uses the existing `atomic_write` helper (write `.tmp` → rena
|
||||
|
||||
| Error | Detection | User-facing message | Recovery |
|
||||
|---|---|---|---|
|
||||
| Bad magic | First 4 bytes ≠ `"RBAK"` | `"not a relicario backup file"` | Verify file |
|
||||
| Unsupported version | Version byte > current (1) | `"backup created by a newer relicario; upgrade required"` | Update binary |
|
||||
| Bad magic | First 4 bytes ≠ `"RBAK"` | `"not a Relicario backup file"` | Verify file |
|
||||
| Unsupported version | Version byte > current (1) | `"backup created by a newer Relicario; upgrade required"` | Update binary |
|
||||
| Wrong backup passphrase | AEAD authentication fails | `"wrong backup passphrase, or the file is corrupt"` (deliberately ambiguous) | Retry |
|
||||
| Target dir already has a vault | `target/.relicario/` exists | `"target dir already contains a relicario vault; restore refuses to overwrite — use an empty directory"` | Choose empty dir |
|
||||
| Schema mismatch | envelope.schema_version != current | `"backup is schema v<N>; this relicario reads v<M>"` | Use matching binary |
|
||||
| Target dir already has a vault | `target/.relicario/` exists | `"target dir already contains a Relicario vault; restore refuses to overwrite — use an empty directory"` | Choose empty dir |
|
||||
| Schema mismatch | envelope.schema_version != current | `"backup is schema v<N>; this Relicario reads v<M>"` | Use matching binary |
|
||||
| Mid-restore crash | (no detection) | — | User deletes target dir, retries |
|
||||
|
||||
Atomicity: best-effort. If interrupted mid-write, target dir has partial files — user cleans up and retries. Documented limitation. Restore is rare enough that engineering atomic-rename of multiple files is not worth the complexity.
|
||||
|
||||
Reference in New Issue
Block a user