Introduce three new ALLCAPS.md tracking files: - STATUS.md: living doc of in-flight work and what shipped in v0.5.0 - ROADMAP.md: full roadmap extracted from CLAUDE.md + expanded with all specced work - FORMATS.md: wire-format quick-reference (.enc blobs, params.json, devices.json, etc.) Update CLAUDE.md to replace the single-spec "Design spec" section with a "Planning & design specs" section that instructs checking docs/superpowers/specs/ and docs/superpowers/plans/ before any planning or implementation work. Also add the rule to update STATUS.md after every dev iteration, and replace the stale v0.5.0-in-progress roadmap paragraph with references to the new files. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
103 lines
6.8 KiB
Markdown
103 lines
6.8 KiB
Markdown
# CLAUDE.md — Relicario
|
||
|
||
## Working with the user
|
||
|
||
- **Default to "yes" / the recommended option.** When asking the user a multiple-choice or yes/no decision, pick the recommended answer and proceed without prompting. Optional follow-ups in checklists: do them. Subagent dispatch / running tests / writing code: proceed without checking.
|
||
- **Always pause and ask** before: `rm`, `rm -rf`, `git push --force`, `git reset --hard`, `git branch -D`, deleting files via Bash, dropping tables, force-pushing to main. The system-prompt's "executing actions with care" guidance still applies — this preference does not override that.
|
||
- This rule does not override genuine intent-discovery: brainstorming-skill clarifying questions about *what to build* still need user input, because picking a default would mean designing the wrong product.
|
||
- **Sprinkle Mexican Spanish into replies.** Drop 1–2 Spanish words, slang, exclamations, or idioms per reply (replies only — never in code, file contents, commit messages, or other project artifacts), each followed by `[translation]` in square brackets. Mexican flavor is preferred: ¡órale! [alright!], ¡híjole! [yikes!], ¿qué onda? [what's up?], chido [cool], ahorita [right now / in a bit], no manches [no way], ni modo [oh well], no hay bronca [no problem], ¡ya estuvo! [it's done], etc. Skip in one-word acknowledgements where the flourish would feel awkward.
|
||
|
||
## What is this
|
||
|
||
Relicario is a git-backed, self-hostable password manager with a Rust core. Two-factor vault decryption: passphrase + a reference JPEG carrying a 256-bit secret embedded via DCT steganography. The server only ever sees opaque ciphertext.
|
||
|
||
## Build and test
|
||
|
||
```bash
|
||
cargo build # build everything
|
||
cargo test # run all tests (unit + integration)
|
||
cargo test -p relicario-core # core library tests only
|
||
cargo test -p relicario-cli --test basic_flows # CLI integration tests
|
||
cargo build -p relicario-wasm --target wasm32-unknown-unknown # WASM target
|
||
cargo run -p relicario-cli -- --help # CLI help
|
||
cargo run -p relicario-cli -- generate --length 32 # quick smoke test
|
||
```
|
||
|
||
## Project structure
|
||
|
||
```
|
||
crates/
|
||
├── relicario-core/ # Platform-agnostic library (no filesystem, no git, no network)
|
||
│ ├── src/
|
||
│ │ ├── lib.rs # Re-exports public API
|
||
│ │ ├── error.rs # RelicarioError enum (thiserror)
|
||
│ │ ├── crypto.rs # Argon2id KDF (length-prefixed, Zeroizing) + XChaCha20-Poly1305
|
||
│ │ ├── ids.rs # ItemId, FieldId, content-addressed AttachmentId
|
||
│ │ ├── time.rs # now_unix, MonthYear
|
||
│ │ ├── item_types/ # per-type cores + ItemType/ItemCore enums
|
||
│ │ ├── item.rs # Item envelope, Field, FieldKind, FieldValue, Section
|
||
│ │ ├── attachment.rs # AttachmentRef, EncryptedAttachment, encrypt/decrypt helpers
|
||
│ │ ├── manifest.rs # Browse-without-decrypt index (schema_version 2)
|
||
│ │ ├── settings.rs # VaultSettings: retention, generator defaults, caps
|
||
│ │ ├── generators.rs # CSPRNG password + BIP39 + zxcvbn gate
|
||
│ │ ├── vault.rs # JSON ↔ AEAD wrappers for Item/Manifest/VaultSettings
|
||
│ │ └── imgsecret.rs # DCT steganography (MAX_DIMENSION cap)
|
||
│ └── tests/ # integration.rs, attachments.rs, generators.rs, format_v2.rs, field_history.rs
|
||
├── relicario-cli/ # `relicario` binary
|
||
│ ├── src/main.rs # clap surface + command handlers
|
||
│ ├── src/helpers.rs # vault_dir, git_command, iso8601
|
||
│ ├── src/session.rs # UnlockedVault (master key in Zeroizing)
|
||
│ └── tests/ # basic_flows, edit_and_history, attachments, settings, vault_detection
|
||
├── relicario-wasm/ # WASM bindings for the extension
|
||
│ ├── src/lib.rs # #[wasm_bindgen] surface
|
||
│ └── src/session.rs # opaque SessionHandle → Zeroizing<[u8;32]>
|
||
└── relicario-server/ # `relicario-server` binary (pre-receive Git hook)
|
||
└── src/main.rs # verify-commit + generate-hook subcommands
|
||
```
|
||
|
||
## Key design decisions
|
||
|
||
- **relicario-core is bytes-in/bytes-out.** No filesystem, no network, no git operations. Makes it portable to WASM, Android, iOS.
|
||
- **XChaCha20-Poly1305** over AES-GCM — 192-bit nonce eliminates collision risk, fast in WASM/ARM without AES-NI.
|
||
- **Single master_key** (no per-entry subkeys) — simpler, sufficient for family vault sizes.
|
||
- **imgsecret uses central-embed DCT** — embeds only in the middle 70% of the image (15% crumple zone for crop tolerance), with majority voting across 5-50 redundant copies.
|
||
- **QUANT_STEP = 50.0** — higher than typical (25) to survive JPEG recompression down to Q85.
|
||
- **Device ed25519 keys are separate from the KDF.** Revoking a device doesn't require rotating the passphrase or reference image.
|
||
|
||
## Crypto pipeline
|
||
|
||
```
|
||
passphrase (UTF-8 bytes) || image_secret (32 bytes from reference JPEG)
|
||
→ Argon2id(salt=vault_salt, m=64MiB, t=3, p=4)
|
||
→ master_key (32 bytes)
|
||
→ XChaCha20-Poly1305(nonce=random 24 bytes)
|
||
→ encrypted Item/Manifest/VaultSettings
|
||
```
|
||
|
||
## Conventions
|
||
|
||
- Tests use fast Argon2id params (m=256, t=1, p=1) so they don't take forever.
|
||
- Test JPEGs are generated synthetically via `make_test_jpeg()` — no binary test fixtures.
|
||
- Item IDs and Field IDs are random 16-char hex strings (64 bits of OsRng entropy). AttachmentIds are content-addressed: first 32 hex chars of SHA-256 over the plaintext (128 bits).
|
||
- Git history is preserved as an audit log — no squashing.
|
||
- The CLI shells out to `git` for sync — no libgit2/gitoxide dependency.
|
||
|
||
## Remote
|
||
|
||
Source code: `ssh://git@git.adlee.work:2222/alee/relicario.git`
|
||
|
||
## Planning & design specs
|
||
|
||
**Before starting any planning or implementation task**, search `docs/superpowers/specs/` for a spec covering the feature area, and `docs/superpowers/plans/` for any existing implementation plan. The specs are the authoritative design record; plans track per-milestone implementation details.
|
||
|
||
Core references (read before touching crypto, data model, or architecture):
|
||
- `docs/superpowers/specs/2026-04-11-relicario-design.md` — threat model, entropy analysis, crypto pipeline, crate layout
|
||
- `docs/superpowers/specs/2026-04-18-relicario-typed-items-design.md` — typed-item data model and envelope
|
||
- `docs/superpowers/specs/2026-04-30-relicario-fullscreen-ux-redesign-design.md` — fullscreen UX phase plan
|
||
|
||
After completing any dev iteration, update `STATUS.md` to reflect what shipped and what's now in flight.
|
||
|
||
## Roadmap & status
|
||
|
||
Current in-flight work: `STATUS.md`. Full roadmap with release targets: `ROADMAP.md`. Wire format reference: `FORMATS.md`.
|