Doc-audit Finding 1. The repo has had four Rust crates since early May
when the pre-receive hook crate landed, but docs/architecture/overview.md
still framed itself around three. Update:
- "The three codebases" → "The four codebases" (intro + heading)
- ASCII diagram fans core out to cli + server + wasm, with wasm feeding
the extension
- Table gains a relicario-server row noting it lives on the git server
and only sees public key material
- Build matrix adds `cargo build -p relicario-server --release`
- "Where to look next" points at server src + the device-auth design spec
Server has no user-facing surface, so the CLI/extension parity rule is
clarified to exclude it (it is server-side enforcement of an invariant
the clients already agreed to).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Three-terminal coordination paradigm: a PM session reviews and
integrates while two senior-dev sessions work parallel feature
branches in their own worktrees, dispatching subagents per
task. Prompts encode roles, boundaries, status/directive/question
block formats for user-relayed cross-terminal coordination, and
pre-tag checklists.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Anchors on a HIGH-severity auth bypass in the relicario-server
pre-receive hook (revocation + registered-device checks both
unimplemented), bundles two hardening follow-ups, two confirmed
bugs, and four UX improvements. Splits into Plan A (Rust + docs)
and Plan B (extension UX) for independent merge cadence.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
13-task plan to land patina palette, polish vocabulary (.surface-backdrop,
.glass, .btn-primary/secondary, ▸ arrow glyph), restructured login popup,
setup wizard polish, two-column login form, sticky save bar, and dirty-
state header subtitle.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Bundles patina palette shift, logo update (translucent gradient gem),
glass-card vocabulary across login/setup/fullscreen, and the original
two-column form layout. Updates relicario-logo.svg and -16.svg to the
patina palette.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Two-column CSS Grid for login forms, sticky save bar, and dirty-state
header subtitle. Other item types stay single-column with the polish
applied. Stacks to single column at <=720px viewport.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Clarifies what AEAD protects (tampering) vs. what it doesn't (deletion,
rollback). Documents that git history is the audit trail and device
authentication is the mitigation.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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>
18 tasks across 8 phases covering all 8 form-level smart-input
affordances from spec section C (popup + fullscreen share login.ts) plus
CLI parity (rate, --totp-qr, completions + groups.cache). Cross-plan
coordination notes flag overlap with Phases 2B (recovery-QR) and 2C
(password coloring) — no conflicts, only shared APIs (rate_passphrase,
strength widget).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Two implementation plans, one per spec landed in 00da7e7. Each plan
decomposes its spec into bite-sized TDD tasks with exact file paths,
complete code, and per-task commits.
- recovery-qr-and-entropy-floor.md (15 tasks, 6 phases): core crypto
module + wasm bindings + CLI subcommands (imgsecret embed, recovery-qr
generate/unlock, --force-weak-passphrase) + extension popup window
with canvas QR + vault-tab button + unlock-flow recovery link +
zxcvbn>=3 hard gate at init (CLI + setup wizard) + soft warning at
unlock for grandfathered weak vaults.
- password-coloring.md (9 tasks, 6 phases): pure colorizePassword()
utility + chrome.storage.sync round-trip + applyColorScheme() boot
step + four reveal-surface integrations (field history, popup item
detail, fullscreen item detail, generator preview) + settings UI
with color pickers and live-preview swatch. Task 6 (fullscreen)
flagged for coordination with in-flight Phase 1 UX work.
Both plans follow the subagent-driven execution preference per
feedback_subagent_default.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Two design specs landed together because they're driven by the same
brainstorm session and target the same release window:
- 2026-05-01-recovery-qr-design.md: 1-of-2 disaster recovery via a
paper-or-photo QR carrying image_secret encrypted under Argon2id-of-
passphrase. Display-first UX (snap with phone), print as secondary.
Memory-only — architecturally no API path produces a file. Includes
domain-separation tag, type-level KDF params floor, shared NFC
normalization helper, and a passphrase entropy floor (zxcvbn >= 3)
enforced at vault init.
- 2026-05-01-password-coloring-design.md: 1Password-style character-
class coloring on revealed passwords (digits/symbols/letters with
user-customizable colors via chrome.storage.sync). Single shared
colorizePassword() helper, default scheme blue/red/inherit.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Code-review feedback on Task 1: the _HTML suffix makes the 'this is raw
HTML, do not escape' contract obvious at every call site. Cheap to do
now (zero consumers); would be 8 diffs once Tasks 4-6 wire the constant
into the type forms.
Plan updated in lockstep so Task 4 references the new name.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eight bite-sized tasks for the visual baseline: shared/glyphs.ts module,
color-token & focus-ring CSS in popup and vault, .req-pill class, migration
of all ten required-marker sites and ten emoji glyph sites to the shared
constants, gating of the popout-to-tab button on !isInTab(), and a static
"esc to cancel" subtitle in fullscreen forms.
Each task pairs a failing test with a minimal implementation; ends with a
commit. Sets the visual language that phases 2-4 build on.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Captures the brainstorm output for the fullscreen vault tab: two-column login
form with sticky save bar, monospace-coherent glyph buttons, eight smart-input
affordances (fill-from-tab, hostname chip, group autocomplete, password reveal
& strength, TOTP live preview, TOTP-from-QR, notes monospace), and seven
power-user features (three-pane shell, keyboard nav, ⌘K palette, unsaved guard,
multi-select bulk ops, drag-drop attach, recent items).
Includes a CLI-parity section pairing each extension capability with its CLI
counterpart so the surfaces ship together.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The repo uses bun (bun.lock present, no pnpm/npm available).
Replaces all pnpm references in the plan with bun equivalents.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Plan 3A: backup & restore — drives the feature branch landing in
the next commit (merge of feature/backup-restore).
Pre-v0.3.0 audit checklist: manual smoke-test list for the v0.2.x
audit-pass commits (TOTP edit, history, detach, status, generator
defaults, vault-tab parity, sync button) — to walk through before
the v0.3.0 tag.
Strategic-depth architecture documentation, the kind that's hard to
recover by reading code: invariants, multi-file flows, design rationale,
gotchas. Goal is to cut the token cost for future Claude sessions.
Four new docs (2091 lines total):
- crates/relicario-core/ARCHITECTURE.md (514 lines) — bytes-in/bytes-out
boundary, 24 verified invariants (VERSION_BYTE=0x02, length-prefixed
KDF input, NFC normalization, content-addressed AttachmentId, history-
tracked field kinds, 60% imgsecret confidence floor, MAX_DIMENSION=
10000, etc.), 7 multi-module flows, 16 non-obvious gotchas (QUANT_STEP=
50, central-70%-embed, BIP39-128bit-then-truncate, Steam alphabet
rationale).
- crates/relicario-cli/ARCHITECTURE.md (539 lines) — module map for the
three source files; the cmd_add/cmd_edit per-type helper pattern (post-
2026-04-27 refactor); the hardened-git invariant (Command::new("git")
is gated to helpers.rs:46); the five history synthetic keys; the env-
var escape-hatch policy; cmd_generate's two-mode design (no-unlock
outside vault, unlock-and-read-defaults inside).
- extension/ARCHITECTURE.md (831 lines) — five-bundle structure (popup,
vault, setup, content, service-worker); SW-as-crypto-fortress model;
capability-set-or-silent-rejection contract; vault-tab-as-popup-class
router parity (commit a7dbf35); origin TOFU flow; setup state machine;
test-vs-build gap.
- docs/architecture/overview.md (207 lines) — cross-codebase entry point.
How the three codebases fit together, the four versioned wire formats
between them (core→WASM ABI, SW chrome.runtime protocol, vault on-disk
layout, GitHost API), per-codebase secret residency table, build
matrix, conventions that span all three.
Specs in docs/superpowers/specs/ remain as historical decision artifacts
("why we chose this") — the new arch docs are the source of truth for
"what is" current invariants and flows.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Brainstormed scope: backup/restore round-trippable to relicario, plus a
LastPass CSV importer. Migration out is explicitly out of scope. CLI and
fullscreen vault tab get parity; popup is untouched.
Backup format `.relbak` v1: magic header + version + Argon2id salt +
XChaCha20-Poly1305 nonce + AEAD-encrypted, zstd-compressed JSON envelope
with base64'd binary blobs. KDF params are tied to backup format
version, not the live vault's params.json.
Reference image inclusion is opt-in; .git history is opt-out. Backup
passphrase is independent of the vault passphrase. Restore refuses if
the target dir already has a vault.
Includes architecture, data flow, error handling, testing strategy,
LastPass field-mapping table, risks, and effort estimate (~5.5 dev-days
for full CLI + extension parity).
Implementation plan and code to follow.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Setup wizard currently overwrites existing vaults silently. Adds a
mode picker (create new / attach this device), a vault-presence probe
after the connection test, and a Step 3b that verifies passphrase +
reference image by decrypting the manifest before registering a new
device key. Refuses destructive overwrite from the GUI; users wanting
a clean slate must delete the repo via their host's web UI.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Four features completing Plan 1C: device ed25519 keypair registration
during setup wizard, device management UI, trash view with restore/purge
(including orphan blob cleanup), per-item field history view, and
per-attachment size cap setting in vault settings.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The previous commit (f963ae3) used per_item_max_bytes and per_vault_*_max_bytes
which don't match the Rust core's struct (per_item_max_count and
per_vault_*_cap_bytes). Also fixes the per-item semantics: it's a COUNT of
attachments per item, not a byte sum.
Spec and plan docs updated in-place so future Task 7 cap-enforcement
implementation uses the correct names + semantics.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wires Rust attachment-encrypt surface into the extension. Adds GitHost
putBlob/getBlob/deleteBlob ops with Git Data API fallback for blobs
>900 KB (Contents API base64-bloats and rejects past ~1 MB). Adds the
Document item type (deferred from β₁ — needs primary_attachment).
UX: compact disclosure for attachments on every typed-item form (matches
β₂ custom-fields pattern). Image-mime rows get 16×16 thumb-icons (lazy
decrypt + object-URL lifecycle). Document detail promotes the primary
attachment to a gold "signature block" matching Totp's pattern. Item-list
gets a 📎 indicator (no count) for items with attachments.
γ₂ (later) covers trash + field-history + device + caps UI.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces the right-anchored popover (which clips off the popup edge)
with an inline panel that injects into the form below the password row.
Trigger becomes a ✨ icon button (gold-bg). "save default" demoted to
secondary link; single gold "use" CTA. Bundles label-casing polish
(drop CAPS LOCK, gold required marker) since .label is shared.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Round chapel-style theca with fleur-de-lis finial replaces the arched
niche + blue gem. Extension primary accent shifts from GitHub blue to
B/C-midpoint burnished gold; danger red shifts to theca tone. Backgrounds
and text stay GH-dark to keep the CLI feel.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Third β sub-plan. Adds cross-cutting UI surfaces on top of β₁'s typed-
item forms:
- Custom-fields editor: collapsible disclosure in edit forms; sections
+ fields of kind Text/Password/Concealed (other 8 FieldKinds deferred).
No reordering. Always-visible below typed rows in detail mode.
- Full VaultSettings view: trash retention, field-history retention,
generator defaults (preview + "configure" link to the popover),
autofill origin-ack revoke. Skip attachment caps (γ concern).
- Inline generator popover: invoked at every "gen" button. Random/BIP39
kind toggle, length/word-count slider, charset checkboxes. Actions:
use this value / save as default / reset / cancel. Shared with the
Settings screen's "configure ▾" button.
- Two new popup-only messages: get_vault_settings / update_vault_settings
(thin wrappers around α's fetchAndDecryptSettings / encryptAndWrite-
Settings). NOT in SETUP_ALLOWED.
- generate_passphrase message added if missing for BIP39 previews.
Five-slice sequencing in execution order:
1. Custom-fields detail rendering (read-only)
2. Custom-fields edit rendering (disclosure + add/remove)
3. Vault-settings SW plumbing (+ generate_passphrase if needed)
4. Generator inline popover
5. Settings view + origin-ack revoke + default wiring
Slice 3 intentionally lands before Slice 4 so the popover's "save
as default" action is fully functional the moment it ships.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Second sub-plan after 1C-α. Adds the 5 remaining typed-item forms
(SecureNote, Identity, Card, Key, Totp) so the extension can daily-
drive every typed item the Rust core supports — Document deferred
to γ for attachment dependencies.
Form style: muted "signature block + uniform rows" pattern
(per-type accent panel + plain rows for the rest). Login is
refactored onto a shared field-helper module as the reference
implementation.
Totp covers `kind: 'totp'` and `kind: 'steam'`. The latter requires
a Rust-core fix (Slice 1) — `compute_totp_code` currently produces
decimal output for Steam but Steam Guard uses a 5-char alphabet
(`23456789BCDFGHJKMNPQRTVWXY`). Plan ships the alphabet patch and
RFC-style test vectors.
Five-slice sequencing: Rust Steam → shared helpers + Login
refactor → SecureNote+Identity → Card+Key → Totp.
Custom fields editor, vault-settings view, advanced generator UI
all moved to β₂. Hotp counter UI deferred. Document type stays in γ.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bug: setup tab's zxcvbn meter silently stayed at score=-1 because the
router's isSetup exception only allowed save_setup, so rate_passphrase
got unauthorized_sender. Result: the "create vault" button stayed
disabled forever even with a strong passphrase.
Fix: add a narrow SETUP_ALLOWED set containing save_setup,
rate_passphrase, and is_unlocked (step-4 extension detection). Reject
everything else from the setup tab. Also clean up setup.ts's unlock
call — it was passing the raw 32-byte imageSecret where JPEG bytes with
embedded secret are required; the Rust-side unlock calls imgsecret::
extract internally.
Diagnostic logging across the message path so the next silent failure
speaks up:
- [relicario setup] staged logs through vault-init; console.error
with the failure stage name in the UI banner.
- [relicario setup] rate_passphrase lastError / rejected / threw
branches each log their own warning.
- [relicario router] console.warn on unauthorized_sender (with sender
classification) and unknown_message_type.
- [relicario sw] first-message wasm init announced; per-message
non-ok result logged; thrown errors console.error'd.
Tests: +3 setup-allowlist tests (rate_passphrase accepted, is_unlocked
accepted, fill_credentials + unlock rejected). 55/55 green.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Verified against the Plan 1A Rust sources:
- ItemType / ItemCore use snake_case with tag="type" internal tagging
(not the external tagging I initially wrote)
- TotpKind is default-externally-tagged (no tag attr), so it serializes
as bare "totp"/"steam" for unit variants and { hotp: { counter } }
- GeneratorRequest uses tag="kind" internal tagging
- FieldValue / TrashRetention / HistoryRetention / SymbolCharset use
adjacent tagging { tag: "kind", content: "value" }
- Fix Login form TOTP parse example and "gen" button payload
No scope change — this is a bookkeeping correction so the plan
author references the correct wire shapes.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Foundation slice of the browser-extension migration onto the typed-item
core from Plans 1A+1B. Scope: WASM artifact rebuild, typed-item shared
types, SessionHandle-based service worker, split router with sender
checks, full security architecture (origin-bound autofill, TOFU ack,
closed Shadow DOM, popup captured-tab verification), zxcvbn setup gate,
Login-parity popup. Other 6 item types land in 1C-β; attachments/trash/
history/device UI in 1C-γ.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
A Task 6 implementer subagent ran `relicario init` inside the worktree
root during manual testing and committed the resulting vault skeleton
(.relicario/, manifest.enc, settings.enc) plus overwrote .gitignore.
None of these should be in the source repo.
Restores the original .gitignore (adds reference.jpg and ref.jpg to it)
and checks in the Plan 1B design doc that describes the work just merged.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
31 bite-sized TDD tasks covering: ID types, time helpers, error rewrite,
crypto fixes (length-prefix KDF, Zeroize, NFC, VERSION_BYTE 0x02), seven
typed cores with per-type modules, Field/FieldKind/FieldValue/Section,
Item envelope with field_history + soft-delete, AttachmentRef + content-
addressed encrypt/decrypt, Manifest with schema_version 2, VaultSettings,
CSPRNG generators with safe charset, BIP39 + zxcvbn strength gate, vault
helpers, retention pruning, full integration test suite.
idfoto-cli is expected to fail compilation at the end of this plan;
Plan 1B fixes it.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>