Files
relicario/CHANGELOG.md
adlee-was-taken 2de250a41e docs: promote overview.md to root ARCHITECTURE.md + add update discipline table
Move docs/architecture/overview.md to ARCHITECTURE.md at the repo root —
it is the primary cross-codebase architecture doc (four-codebase diagram,
inter-codebase contracts, secrets map, build matrix, test strategy, where-to-look
table) and belongs at the root alongside STATUS.md, ROADMAP.md, etc.

Update relative paths inside the file (../../crates/ → crates/, etc.).
Update CHANGELOG.md's one active reference to the old path.

Add a "Living docs — update discipline" table to CLAUDE.md that maps every
ALLCAPS.md file to the area it covers and the trigger for updating it. This
closes the loop on the ALLCAPS.md documentation system.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 19:44:30 -04:00

12 KiB
Raw Permalink Blame History

Changelog

v0.5.0 — 2026-05-02

Three release trains roll into one tag — backup/restore + LastPass import (originally v0.3.0), device authentication (originally v0.4.0), and the v0.5.0 polish + harden bundle (security fixes + UX fixes + two confirmed bugs).

Security

  • Pre-receive hook now actually verifies signatures (audit S1, HIGH). Earlier relicario-server builds accepted any commit with a Good signature line on stderr regardless of which key signed it — device-auth was a no-op. The hook now builds an allowed_signers file from devices.json at the commit (via GIT_CONFIG_* env, no global git-config mutation), parses the SSH SHA-256 fingerprint out of git verify-commit --raw stderr, and rejects unregistered keys or revoked keys whose committer-date is at or after the revocation timestamp. Bootstrap mode is preserved only when both devices.json AND revoked.json are empty (closes an empty-devices.json privilege-escalation route).
  • Backup-restore tar unpacking hardened (audit S2). relicario backup restore no longer trusts tar::Archive::unpack's defaults. A new relicario_core::safe_unpack_git_archive validates each entry's path components (rejects .., absolute paths, Windows drive prefixes), rejects symlinks/hardlinks, and caps total uncompressed size at the lower of 100×compressed-bytes or 1 GiB. The CLI restore path adds a paranoid dest.starts_with(.git/) check after path-joining as defense-in-depth.
  • RELICARIO_* env-var surface audited (audit S3). docs/SECURITY.md gains a per-variable trust table. RELICARIO_NO_GROUPS_CACHE (a developer escape hatch, not a user knob) is now cfg(debug_assertions)-gated and is a no-op in --release builds; the env-var lookup is removed from the binary by the optimiser.

Fixed

  • Strength meter no longer goes stale after the regenerate button (B1). Programmatic input.value = newPassword doesn't fire input events; the regenerate handler now dispatches a synthetic InputEvent('input', { bubbles: true }) so the meter listener re-rates the new value.
  • Snake_case error codes no longer leak into the UI (B2 / P4). Errors like vault_locked, origin_mismatch, unauthorized_sender used to render verbatim in the fullscreen vault tab and (in some cases) the popup. New extension/src/shared/error-copy.ts central registry maps every service-worker error code to friendly title/body/CTA copy; the popup and fullscreen tab consume the same map. The fullscreen lock screen's vault_locked block now reads Vault locked / Unlock your vault to continue. / [Unlock vault]. A generated test enumerates the live error codes via grep so the registry can't drift.

Added

  • Sidebar logo in the fullscreen vault tab. The vault-sidebar__header now renders the 16-optimized SVG logo inline before the "Relicario" wordmark (20×20 px, flex-shrink: 0 so it survives narrow-pane wraps). Popup unaffected.
  • Password coloring (P1). Revealed passwords in the popup item-detail, fullscreen item view, field-history viewer, and generator preview render digits and symbols in distinct colors. Defaults: blue digits, red symbols. Users can override via the new Display section in settings (color pickers + live preview swatch + reset). Defaults round-trip via chrome.storage.sync.password_display_scheme; cross-device when Chrome sync is enabled.
  • Setup wizard hands off to the fullscreen vault tab on completion (P2). Both create-new and attach-existing flows now open vault.html in a new tab and best-effort close the setup tab after device registration succeeds — replaces the prior setup-tab-stays-open terminal screen.
  • Sync now button in the extension settings view — surfaces the previously hidden { type: 'sync' } SW message to users with success / error feedback.
  • Device registration from the popup. The "Register this device" button on the devices view now opens an inline name input and (on confirm) generates a keypair via WASM, persists the private key + name locally, and writes the device to the remote — no setup-wizard detour. Backed by a new register_this_device SW message.
  • relicario settings generator-defaults — view-and-edit access to the generator defaults stored in VaultSettings. Flags: --random / --bip39 to switch mode, --length, --words, --symbols, --separator to update fields of the active mode.
  • relicario edit now supports TOTP items. Issuer, label, and secret rotation work; rotated secrets are pushed to field_history (key: core:totp_secret).
  • relicario history <query> — view captured field history. Values are masked by default; --show reveals them; --field <name> filters to one synthetic key (e.g. login_password, totp_secret).
  • relicario detach <query> <aid> — remove an individual attachment from an item. Refuses to drop a Document item's primary attachment (use purge instead).
  • relicario status — vault summary: root path, item count (active / trashed), attachment count + total bytes, registered device count, last commit (%h %s).
  • Backup & restore. New relicario backup export <out.relbak> and relicario backup restore <in.relbak> [<dir>] commands. The .relbak format is a single encrypted file: Argon2id-derived key from a user-chosen backup passphrase (independent of the vault factor), XChaCha20-Poly1305 ciphertext, zstd-compressed JSON envelope. Reference image and .git/ history are opt-in inclusions (--include-image, --no-history).
  • Vault-tab Backup & Restore panel. Export downloads the .relbak via chrome.downloads. Restore takes a file + backup passphrase + new-remote config and writes the vault into a fresh empty repo (refuses to clobber existing). Git history is never bundled from the extension — CLI is the source of full backups.
  • LastPass CSV import. New relicario import lastpass <csv> command + vault-tab Import panel (vault.html#import). Logins map to Login items; rows with url == "http://sn" map to SecureNote (extra column → body verbatim, structured data preserved as-is for manual re-categorization). TOTP secrets in the totp column are base32-decoded into LoginCore.totp; bad base32 surfaces a warning and the login is imported without TOTP. Failed rows (missing name, missing password on a login) are skipped with a per-row warning. Each row gets a freshly-minted ID — re-running the import creates duplicates rather than corrupting state.
  • Popup deep link to the Import panel. settings-vault gains an "import" section with a LastPass CSV → button next to the existing Backup & restore → button.
  • relicario status shows last export age. New Last export: <human-readable> line reading .relicario/last_backup (a marker file cmd_backup_export writes on success). Reads "never" for fresh vaults, "4 days ago" otherwise.

Changed

  • Form layout in the fullscreen vault tab is now visually consistent (P3). Notes, custom-fields disclosure, attachments disclosure, and form-actions in fullscreen logins now sit inside a .form-lower wrapper with the same max-width: 960px; margin: 0 auto envelope as the .form-grid cards above. Removes the visual rhythm break at the 2-col → full-width transition. The popup surface is unchanged.
  • Documentation refreshed for v0.5.0 (doc audit, 14 findings). ARCHITECTURE.md now describes four codebases (the relicario-server pre-receive hook crate is no longer invisible); CLAUDE.md project tree and roadmap reflect current state; docs/SECURITY.md names the server crate and its verify-commit / generate-hook subcommands and notes the without-the-hook-it's- advisory caveat; docs/ARCHITECTURE.md shows settings.enc as a parallel artifact in the vault-creation flow; the foundational design spec gains a "historical" status banner pointing readers at the current docs.
  • relicario generate now consults VaultSettings.generator_defaults when invoked inside an initialized vault. Explicit flags (--length, --bip39, --words, --symbols, --separator) override the vault default. Outside a vault, behavior is unchanged (length 20, safe symbol set, 5 BIP39 words, space separator).

Known limitations

  • Mid-restore failure leaves the target remote in a half-written state. cmd_backup_restore and the vault-tab Restore panel both write artifacts sequentially via writeFileCreateOnly. If the process is interrupted partway, a retry against the same remote refuses to clobber. Workaround: delete the partial repo and retry.
  • Cross-tool backup compatibility. CLI-exported backups stored attachments at <item_id>/<aid>.enc; extension stores at flat <aid>.bin. The .relbak envelope canonicalizes to <item_id>/<aid> keys and each tool translates at the boundary. Round-trip works in both directions.

Internal

  • 5 stale local feature branches and 3 worktrees pruned (audit C1).
  • Pre-existing clippy warnings cleaned up across relicario-{core,cli} (deref operators, Option::is_none_or over map_or(true, ...), iter_mut().enumerate() patterns, div_ceil()) so the workspace builds clean under -D warnings.
  • Cargo.lock regenerated and committed; was stale since the --totp-qr commit.
  • Refactored cmd_add and cmd_edit in the CLI: each ItemCore variant now has its own build_*_item / edit_* helper. Pure mechanical extraction; behavior unchanged. The dispatcher matches and delegates.
  • Extracted pure helpers (escapeHtml, ratePassphrase, scheduleRate, entropyText, STRENGTH_LABELS) from extension/src/setup/setup.ts into setup-helpers.ts. State-coupled updateStrengthUi stays in setup.ts since it walks live wizard state. Setup.ts went from 1205 → 1137 lines.

v0.2.0 — 2026-04-27

Fixed

  • Setup wizard could silently overwrite an existing vault. Pointing the wizard at a remote that already contained a Relicario vault would clobber manifest.enc, .relicario/salt, and friends with no warning. The wizard now probes the remote after the connection test and refuses to create a new vault on top of an existing one. Affected users whose vault was wiped by this bug should restore from the git history of the affected repo (git log + git checkout <pre-init-sha> -- .).
  • New devices registered during initial setup were silently dropped. The wizard's Step 5 fired add_device over a service-worker channel that required an unlocked vault, which is unavailable mid-wizard. Device pubkeys now write directly to .relicario/devices.json from the wizard.
  • Wizard-created vaults were missing settings.enc. The CLI's init writes a default-VaultSettings settings.enc alongside manifest.enc, but the wizard skipped it, causing every get_vault_settings SW call to 404. The wizard now encrypts and writes settings.enc using a new default_vault_settings_json WASM helper that keeps defaults in sync with Rust core.

Added

  • Attach this device to an existing vault — purely from the GUI. New Step 0 mode picker splits the wizard into "create new vault" and "attach this device." The attach path takes a passphrase + reference image, fetches the existing manifest, verifies the credentials by decrypting it, and only then registers a new device key. No CLI required for multi-device setup.
  • GitHost.lastCommit(path) and GitHost.writeFileCreateOnly(path, ...).
  • default_vault_settings_json() WASM export.

v0.1.0 — 2026-04-22

Initial release.