Completes the extension restructure begun in v0.6.0. Phases 3 (setup wizard SW migration + step registry), 4 (vault.ts split + vault_locked lift), and 6 (get_vault_status + sidebar status indicator) all merged to main (9df2fee,3b8368d,397cc78) via three parallel worktree streams. This commit is the release-prep wrap-up: - Version bump to v0.7.0 across the three relicario crates + Cargo.lock, extension/package.json, and both extension manifests (the manifests had lagged at 0.5.0 — corrected here). - CHANGELOG.md v0.7.0 entry. - STATUS.md: extension restructure moved to shipped; Phases 3/4/6 landing section added. - ROADMAP.md: v0.7.0 row added; Up-next now command palette. - extension/ARCHITECTURE.md: all three phases integrated (new vault-* modules, setup-steps.ts, get_vault_status protocol + status indicator, vault_locked lift, git-host sync cache). - Plan completion checkboxes ticked. Task 7.1 verification: done-criteria sweep all green; 423/423 vitest; build:all clean (only the pre-existing 4MB WASM size warning). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
23 KiB
Changelog
v0.7.0 — 2026-06-01
Completes the extension restructure (Plan C) begun under v0.6.0. Phases
1/2/5 (StateHost typing, SW storage extract, the P2 cluster) shipped
2026-05-30; this tag adds the remaining three phases — executed as three
parallel worktree streams under PM coordination — which eliminate the
two steepest learning cliffs in the extension and close the last
relicario status CLI/extension parity gap. No crypto, wire-format, or
Rust-API changes; this is an internal-architecture + one-feature release.
Added
relicario statusparity in the extension. Newget_vault_statusservice-worker message returns a cached sync summary{ ahead, behind, lastSyncAt, pendingItems }with no network call —ahead/behind/lastSyncAtread straight off the cached git-host state (populated by thesynchandler),pendingItemsa live count of active (non-trashed) manifest entries. A sidebar-footer status indicator (vault-status.ts→renderStatusIndicator) rendersN pending/N ahead/N behind/in syncplus alast sync …/never syncedline, refreshed on mount and on a manual↻button — no timer polling, matching the no-network-without-user-intent discipline.
Changed
- Setup wizard crypto moved into the service worker. The wizard no
longer imports
relicario-wasmor orchestrates the master key directly. Newcreate_vault/attach_vaultSW handlers own the full flow (image-secret embed/extract, unlock, manifest+settings encrypt + push,register_device+addDevice, persist config + reference image,session.setCurrent); on failure the SessionHandle is locked then freed, with ownership transferring only on success.setup.tscollapses from ~1230 LOC to a 58-LOC UI-only shell; the six render/attach step pairs become aSetupStepregistry in the newsetup/setup-steps.ts. AddsclearWizardState(bound tobeforeunloadandgoto('mode')) to wipe sensitive Uint8Array fields when the wizard is abandoned. The non-extension copy-vault-config-JSON escape hatch is preserved. vault.tssplit from a 1037-LOC monolith to 194 LOC of routing + state. Extracted into five focused modules —vault-shell(DOM scaffolding, color-scheme, onMessage wiring),vault-sidebar(category nav, 80ms debounced search, bottom nav, status-indicator footer),vault-list(list + row rendering),vault-drawer(open/close/render +ensureDrawerClosedForRoute),vault-form-wrapper(wrapped form + sticky bar) — plus two support modules for an acyclic split (vault-context, the VaultController contract;vault-router, hash routing + pane dispatch).vault_lockedRPC intercept unified. Lifted out ofvault.tsinto thesendMessagewrapper inshared/state.ts, so both popup and vault-tab surfaces share one lock-redirect path.state.gitHostnow nulled on explicit lock, symmetric with the session-timer expiry path, so the new status indicator can't surface a stalelastSyncAtafter a lock → re-unlock within one service-worker lifetime.
Internal
- Three-stream parallel execution (Dev-A Phase 3, Dev-B Phase 4, Dev-C Phase 6) coordinated via the relay message bus; merges sequenced Phase 3 → 4 → 6 with per-phase done-criteria verification.
- Final merged-tree validation: 423/423 vitest (62 files);
npm run build:allclean for both Chrome and Firefox targets (only the pre-existing ~4 MB WASM asset-size warning). Task 7.1 done-criteria sweep all green. No change towasm.d.ts.
v0.6.0 — 2026-05-30
Rolls up four weeks of post-v0.5.0 work into one tag: the Phase 2B polish foundation, the v0.5.1 train (Streams A/B/C — 3-column vault layout, left-nav settings, Recovery QR), the 1C-γ slice (Document type, attachments, device registration from popup, trash & history UI), the Plan B multi-stream refactor (Cycles 1+2), the vault-tab management surfaces revamp, and the doc-structure redesign. The in-flight scope outgrew the original v0.5.1 plan, so this cuts as a minor bump.
Added
- Recovery QR — 1-of-2 disaster-recovery path.
image_secretis encrypted under an Argon2id-derived key from the passphrase, packed into a 109-byte binary payload (magicRREC+ version 0x01 + salt- nonce + AEAD ciphertext), and rendered as a QR code that is never written to disk. Surfaces:
- Rust core:
relicario-core/src/recovery_qr.rs—generate_recovery_qr/unwrap_recovery_qr/recovery_qr_to_svg. Production KDF params (m=64MiB, t=3, p=4) live behind a private-fields type so they cannot drift. - WASM:
generate_recovery_qr/unwrap_recovery_qrexported; the session now stashesimage_secretso the QR can be regenerated without re-running steganography extraction. - CLI:
relicario recovery-qr generate(TTY render) andrelicario recovery-qr unwrapsubcommands. - Extension: three-state Security settings card (no QR → amber warning; QR exists → green status + show/regenerate; explicit view → modal with print).
- Setup wizard: skippable "generate before you go" banner on the final step.
- Document item type. New typed item for storing a signed document
with a primary attachment. Form takes signature + signed-on date;
detail view renders a signature-block layout. Wired into the popup
add/view/edit dispatchers. Refuses to drop its primary attachment
(use
purgeinstead). - Attachments end-to-end. Service worker uploads attachments via
the GitHost putBlob path (GitHub + Gitea Git Data API with fallback);
popup attachments-disclosure component handles add/remove/download
inside all six item-type forms;
📎indicator shows on item-list rows that have attachments. Per-vault attachment bytes cap is enforced both at attach-time and during backup restore. - Device registration from the popup. "Register this device" triggers an inline name input + WASM keypair generation + persisted device entry — no setup-wizard detour.
- Trash + field-history UI. Trash view shows per-item purge
countdown with restore / per-item purge / empty-all actions.
Field-history view groups changes per field with reveal/copy
glyph buttons. New top-level item-history-index pane lists every
item that has captured history.
#history/<id>route normalizes the legacy#field-history/<id>URL form. - 3-column fullscreen vault tab. Sidebar (200px, type-category nav) + list (flex) + detail drawer (440px, slides in on row click). Below 720px the drawer pushes the list full-pane. Bottom sheet for "new item" type picker uses a pane-only scrim so the sidebar stays interactive.
- Left-nav settings page. Replaces the flat settings dump. Sections grouped Device (Autofill, Display — password coloring) vs Vault (Security — Recovery QR + trusted devices, Generator, Retention, Backup, Import). The standalone Devices sidebar entry is subsumed into Security.
- Two-column login form in fullscreen. Identity (title / URL / group) and Credentials (username / password / TOTP) render as side-by-side glass cards above 720px viewport; single-column at narrow widths. Notes / custom sections / attachments stay full-width below the grid. Sticky save bar at the bottom of the form pane; header shows title + dirty subtitle ("unsaved · esc to cancel" or "no changes") + platform-aware save hint (⌘+S / Ctrl+S).
- Polish vocabulary. Patina gold palette tokens
(
--gold-base#a88a4areplacing the brighter#d2ab43),.surface-backdrop(subtle radial top-glow + 18px grid texture) applied to popup body / setup body / vault body,.glasscard class withbackdrop-filter: blur(8px),.btn-primary/.btn-secondarybutton hierarchy, andGLYPH_NEXT = '▸'replacing ASCII→in next/continue buttons. - Vault lock-screen logo.
<img class="brand-logo">added to the lock-screen render for parity with the popup unlock view and the setup wizard. - Setup wizard Style C. Centered hero card + colored progress track + glyph mode icons, replacing the prior vertical glass-card wizard.
- Toast notification system. Shared
showToast(message, type, durationMs)atextension/src/shared/toast.ts. Used for sync success/failure, copy confirmation, device registration result. Replaces the ad-hocsync-statusdiv. - Empty-state treatments. Popup item list (vault empty / search returns nothing), vault list (section empty) — each gets a centered glyph + headline + hint.
- Per-type glyph icons in popup item rows.
◉ login,◫ secure_note,⊡ totp,▭ card,⌬ identity,⊹ key,≡ document.
Changed
- Vault-tab management surfaces revamp (2026-05-24..05-30).
Settings pane splits synced (cross-device via Chrome storage) from
local (per-browser) controls and gains a session-timeout UI.
Devices pane shows SHA-256 fingerprint + added-by display + inline
two-step revoke confirm via glyph button. Trash pane shows per-item
purge countdown via
daysUntilPurge. Field-history pane gets section headers and reveal/copy glyph buttons. New shared utilities:relative-time.ts(consolidating five duplicate inline copies), webcryptossh-fingerprint.ts, shared section-header / glyph-btn / kv-row / fingerprint CSS. - Emoji sweep. Every remaining UI emoji replaced with a
monochrome glyph constant from
shared/glyphs.ts. The pop-out button is now⧉(U+29C9,GLYPH_VAULT_TAB) instead of⤴. - License switched to GPL-3.0-or-later. Was MIT for the early
prototype phase. License headers +
AUTHORS+ crateCargo.tomlauthors updated. - AttachmentId expanded to 128 bits with
is_validcheck. Backup restore now validates IDs (audit I2 / B4). - Per-vault attachment bytes cap enforced. Both CLI attach and backup restore (audit I3).
Internal
- Plan B multi-stream refactor (Cycles 1+2). CLI
main.rssplit into per-command modules undercrates/relicario-cli/src/commands/with a sharedgit_runhelper. Newprompt_or_flag<T>andprompt_or_flag_optional<T>helpers compress all thebuild_*_itemhelpers.Vault::after_manifest_changewrapper plus a single canonicalParamsFilein the session avoid duplicated file-system rebuilds. Core/WASM seam:base32_decode_lenient,parse_month_year,guess_mimeexported from WASM; CLI parsers migrated torelicario-core::parse. Extractedbase32module from core, deduplicated two RFC-4648 implementations. - Doc-structure redesign (2026-05-30). Renamed
ARCHITECTURE.md→DESIGN.md,docs/ARCHITECTURE.md→docs/CRYPTO.md,FORMATS.md→docs/FORMATS.md. Added scope headers and "Next:" footers to all tour docs so the reading order is canonical.CLAUDE.mdgains a living-docs table and four discipline rules (scope-boundary check, code-constant pinning, new-doc rule, plan-state hygiene). - CLI quality-of-life.
genalias forgenerate,-l/-wshort flags, batched purge incmd_purgeandcmd_trash_empty. - Workspace audit cycle. Stale local branches and worktrees
pruned. Several plan files moved into
docs/superpowers/audits/for the record.
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-serverbuilds accepted any commit with aGood signatureline on stderr regardless of which key signed it — device-auth was a no-op. The hook now builds anallowed_signersfile fromdevices.jsonat the commit (viaGIT_CONFIG_*env, no global git-config mutation), parses the SSH SHA-256 fingerprint out ofgit verify-commit --rawstderr, and rejects unregistered keys or revoked keys whose committer-date is at or after the revocation timestamp. Bootstrap mode is preserved only when bothdevices.jsonANDrevoked.jsonare empty (closes an empty-devices.json privilege-escalation route). - Backup-restore tar unpacking hardened (audit S2).
relicario backup restoreno longer truststar::Archive::unpack's defaults. A newrelicario_core::safe_unpack_git_archivevalidates 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 paranoiddest.starts_with(.git/)check after path-joining as defense-in-depth. RELICARIO_*env-var surface audited (audit S3).docs/SECURITY.mdgains a per-variable trust table.RELICARIO_NO_GROUPS_CACHE(a developer escape hatch, not a user knob) is nowcfg(debug_assertions)-gated and is a no-op in--releasebuilds; 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 = newPassworddoesn't fireinputevents; the regenerate handler now dispatches a syntheticInputEvent('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_senderused to render verbatim in the fullscreen vault tab and (in some cases) the popup. Newextension/src/shared/error-copy.tscentral 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'svault_lockedblock now readsVault 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__headernow renders the 16-optimized SVG logo inline before the "Relicario" wordmark (20×20 px,flex-shrink: 0so 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.htmlin 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_deviceSW message. relicario settings generator-defaults— view-and-edit access to the generator defaults stored inVaultSettings. Flags:--random/--bip39to switch mode,--length,--words,--symbols,--separatorto update fields of the active mode.relicario editnow supports TOTP items. Issuer, label, and secret rotation work; rotated secrets are pushed tofield_history(key:core:totp_secret).relicario history <query>— view captured field history. Values are masked by default;--showreveals 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 (usepurgeinstead).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>andrelicario backup restore <in.relbak> [<dir>]commands. The.relbakformat 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
.relbakviachrome.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 toLoginitems; rows withurl == "http://sn"map toSecureNote(extra column → body verbatim, structured data preserved as-is for manual re-categorization). TOTP secrets in thetotpcolumn are base32-decoded intoLoginCore.totp; bad base32 surfaces a warning and the login is imported without TOTP. Failed rows (missingname, 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-vaultgains an "import" section with aLastPass CSV →button next to the existingBackup & restore →button. relicario statusshows last export age. NewLast export: <human-readable>line reading.relicario/last_backup(a marker filecmd_backup_exportwrites 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-lowerwrapper with the samemax-width: 960px; margin: 0 autoenvelope as the.form-gridcards 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).
DESIGN.mdnow describes four codebases (therelicario-serverpre-receive hook crate is no longer invisible);CLAUDE.mdproject tree and roadmap reflect current state;docs/SECURITY.mdnames the server crate and itsverify-commit/generate-hooksubcommands and notes the without-the-hook-it's- advisory caveat;docs/CRYPTO.mdshowssettings.encas a parallel artifact in the vault-creation flow; the foundational design spec gains a "historical" status banner pointing readers at the current docs. relicario generatenow consultsVaultSettings.generator_defaultswhen 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_restoreand the vault-tab Restore panel both write artifacts sequentially viawriteFileCreateOnly. 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.relbakenvelope 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_orovermap_or(true, ...),iter_mut().enumerate()patterns,div_ceil()) so the workspace builds clean under-D warnings. Cargo.lockregenerated and committed; was stale since the--totp-qrcommit.- Refactored
cmd_addandcmd_editin the CLI: eachItemCorevariant now has its ownbuild_*_item/edit_*helper. Pure mechanical extraction; behavior unchanged. The dispatcher matches and delegates. - Extracted pure helpers (
escapeHtml,ratePassphrase,scheduleRate,entropyText,STRENGTH_LABELS) fromextension/src/setup/setup.tsintosetup-helpers.ts. State-coupledupdateStrengthUistays insetup.tssince 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_deviceover a service-worker channel that required an unlocked vault, which is unavailable mid-wizard. Device pubkeys now write directly to.relicario/devices.jsonfrom the wizard. - Wizard-created vaults were missing
settings.enc. The CLI'sinitwrites a default-VaultSettingssettings.encalongsidemanifest.enc, but the wizard skipped it, causing everyget_vault_settingsSW call to 404. The wizard now encrypts and writessettings.encusing a newdefault_vault_settings_jsonWASM 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)andGitHost.writeFileCreateOnly(path, ...).default_vault_settings_json()WASM export.
v0.1.0 — 2026-04-22
Initial release.