From 1758edd5c813ba54812f06cebb9f96e18c878da7 Mon Sep 17 00:00:00 2001 From: adlee-was-taken Date: Fri, 15 May 2026 18:32:12 -0400 Subject: [PATCH] docs: add STATUS/ROADMAP/FORMATS and update CLAUDE.md planning guidance 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 --- CLAUDE.md | 15 +++++--- FORMATS.md | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++ ROADMAP.md | 54 ++++++++++++++++++++++++++++ STATUS.md | 56 +++++++++++++++++++++++++++++ 4 files changed, 223 insertions(+), 4 deletions(-) create mode 100644 FORMATS.md create mode 100644 ROADMAP.md create mode 100644 STATUS.md diff --git a/CLAUDE.md b/CLAUDE.md index 30a74de..7c7cae1 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -86,10 +86,17 @@ passphrase (UTF-8 bytes) || image_secret (32 bytes from reference JPEG) Source code: `ssh://git@git.adlee.work:2222/alee/relicario.git` -## Design spec +## Planning & design specs -Full threat model, entropy analysis, and architecture: `docs/superpowers/specs/2026-04-11-relicario-design.md` +**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. -## Roadmap +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 -Next: v0.5.0 polish + harden (in progress). After that, Phases 3/4 of the fullscreen UX redesign (vault-tab shell + command palette), Plan 1C-γ (attachments + Document + trash/history/device UI), and the LastPass importer. Mobile (Rust core compiles to ARM) and recovery QR remain on the roadmap. +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`. diff --git a/FORMATS.md b/FORMATS.md new file mode 100644 index 0000000..1cae632 --- /dev/null +++ b/FORMATS.md @@ -0,0 +1,102 @@ +# Relicario Wire Formats + +> Quick-reference for the load-bearing binary and JSON formats. Check this file before touching serialization, versioning, or storage layout code. Full diagrams and invariants live in the per-crate `ARCHITECTURE.md` files. + +## Encrypted blob (`.enc` files) + +Every encrypted file — `manifest.enc`, `settings.enc`, `items/.enc`, `attachments//.enc` — uses the layout produced by `relicario_core::crypto::encrypt` (`crypto.rs`): + +``` +┌─────────┬────────────────────────┬──────────────────┬──────────────────┐ +│ version │ nonce │ ciphertext │ auth tag │ +│ 1 byte │ 24 bytes │ N bytes │ 16 bytes │ +│ 0x02 │ random per write │ XChaCha20 stream │ Poly1305 MAC │ +└─────────┴────────────────────────┴──────────────────┴──────────────────┘ +``` + +- `VERSION_BYTE = 0x02` (`crypto.rs:59`). Any blob starting with `0x01` is rejected with `UnsupportedFormatVersion { found: 0x01, expected: 0x02 }`. +- Minimum valid blob length: 41 bytes (1 + 24 + 0 + 16). +- Nonces are always fresh from `OsRng` — no caller-supplied nonces. +- Full diagram: `docs/ARCHITECTURE.md` § "Encrypted File Format". + +## `.relicario/params.json` + +```json +{ + "format_version": 2, + "aead": "xchacha20-poly1305", + "salt_path": ".relicario/salt", + "kdf": { + "argon2_m": 65536, + "argon2_t": 3, + "argon2_p": 4 + } +} +``` + +Parsed via `ParamsFile { kdf: KdfParams }` in `session.rs`. The `kdf` nesting is intentional — `format_version`, `aead`, and `salt_path` co-exist for forward-compat probing. Do not flatten. Production defaults: `m=65536` (64 MiB), `t=3`, `p=4`. Tests use `m=256, t=1, p=1`. + +## `.relicario/salt` + +32 raw bytes. Not secret. Generated once at vault init via `OsRng`. Feeds Argon2id as the KDF salt. + +## Manifest (`manifest.enc`) + +Decrypts to JSON matching the `Manifest` struct (`manifest.rs`). + +- **Schema version:** `MANIFEST_SCHEMA_VERSION = 2` (`manifest.rs:12`). v1 manifests (pre-typed-items) fail to parse and are not supported. +- **`ManifestEntry` fields:** `id`, `title`, `tags`, `favorite`, `group`, `icon_hint`, `modified`, `trashed_at`, `attachment_summaries`. +- The manifest is rebuilt from scratch on every `upsert` — it can never drift from the source-of-truth item files. +- Supports case-insensitive title/tag search without decrypting any item. + +## `.relicario/devices.json` + +```json +[ + { "name": "laptop", "public_key": "" } +] +``` + +An empty array (`[]`) puts the pre-receive hook in bootstrap mode (all pushes accepted). Both `devices.json` and `revoked.json` must be empty for bootstrap mode to activate — a non-empty `revoked.json` alone forces strict verification. + +## `.relicario/revoked.json` + +```json +[ + { "name": "old-laptop", "public_key": "", "revoked_at": 1746000000 } +] +``` + +Commits by `public_key` at or after `revoked_at` (Unix seconds) are rejected by the pre-receive hook. Commits before `revoked_at` remain valid (they were authorized at the time). + +## Item IDs and Field IDs + +| Kind | Length | Entropy | Source | +|---|---|---|---| +| `ItemId` | 16 hex chars | 64 bits | `OsRng` | +| `FieldId` | 16 hex chars | 64 bits | `OsRng` | +| `AttachmentId` | 16 hex chars | content-addressed | first 8 bytes of `SHA-256(plaintext)` | + +`AttachmentId` is content-addressed — identical plaintexts deduplicate in git automatically. + +## `.relbak` backup format + +A zstd-compressed tar archive containing a bare git clone of the vault. Designed for `relicario backup export/restore`. + +Full spec: `docs/superpowers/specs/2026-04-27-relicario-import-export-design.md`. + +## `ItemCore` JSON (internal) + +`ItemCore` uses `#[serde(tag = "type")]` — the outer JSON object gets a `"type"` discriminator key. No `*Core` struct may have a field named `"type"` (use `"kind"` instead — see `CardKind`, `TotpKind`). + +Full item type inventory: `crates/relicario-core/ARCHITECTURE.md` § "Module map". + +## KDF input construction + +The password fed to Argon2id is length-prefixed to prevent extension attacks: + +``` +u64_be(len(passphrase)) || passphrase_bytes || u64_be(32) || image_secret +``` + +NFC-normalized before hashing. Covered in `crypto.rs:229-236` and tested in `tests/format_v2.rs:44-54`. diff --git a/ROADMAP.md b/ROADMAP.md new file mode 100644 index 0000000..8c4d67e --- /dev/null +++ b/ROADMAP.md @@ -0,0 +1,54 @@ +# Relicario Roadmap + +> Living document — update alongside `STATUS.md` when milestones shift. +> "Up next" items have specs; "Medium-term" items may have specs; "Long-term" items are direction, not committed scope. + +## Shipped + +| Version | Highlights | +|---|---| +| v0.5.0 (2026-05-02) | Security audit fixes, device auth, backup/restore, LastPass import, fullscreen UX phases 1+2A | + +See `CHANGELOG.md` for full details. + +## Up next (v0.5.x) + +These are specced and either in progress or immediately queued: + +- **Vault lock screen + container polish** — logo on lock screen, max-width viewport constraint *(in progress)* +- **Phase 2B: form layout** — spacing, section headers, attachment previews in detail pane + Spec: `docs/superpowers/specs/2026-05-02-phase-2b-form-layout-design.md` +- **1C-γ: attachments + Document type** — attachment UI in popup + vault tab; Document item add/view/edit/extract + Specs: `docs/superpowers/specs/2026-04-24-relicario-extension-1c-gamma1-design.md`, + `docs/superpowers/specs/2026-04-26-relicario-extension-1c-gamma2-design.md` +- **v0.5.x UX polish** — recovery QR display in extension, password coloring refinements + Spec: `docs/superpowers/specs/2026-05-03-v0.5.x-ux-polish-and-recovery-qr-design.md` + +## Medium-term + +- **Phase 3: vault-tab shell** — fullscreen sidebar with nav sections, pane routing + Spec: `docs/superpowers/specs/2026-04-27-relicario-vault-tab-design.md` +- **Phase 4: command palette** — ⌘K global search + action dispatch across the vault tab +- **Trash & history UI** — trash view, item history viewer, field-history viewer +- **Device manager UI** — device registration + revocation in vault tab +- **CLI restructure** — subcommand reorganisation, interactive TUI mode + Spec: `docs/superpowers/specs/2026-05-04-cli-restructure-design.md` +- **Extension restructure** — bundle / message-routing cleanup + Spec: `docs/superpowers/specs/2026-05-04-extension-restructure-design.md` +- **Security polish** — `docs/superpowers/specs/2026-05-04-security-polish-design.md` + +## Long-term / backlog + +- **Relay server** — encrypted WebSocket relay for multi-device sync without a shared git server + Spec: `docs/superpowers/specs/2026-05-02-relay-server-design.md` +- **Recovery QR** — QR code encoding of the reference-image secret for printed cold backup + Spec: `docs/superpowers/specs/2026-05-01-recovery-qr-design.md` +- **Mobile** — Rust core compiles to ARM; JNI wrapper for Android, Swift wrapper for iOS +- **Credential capture** — extension content-script form detection + autofill + Spec: `docs/superpowers/specs/2026-04-12-relicario-credential-capture-design.md` + +## Non-goals (explicitly deferred or cancelled) + +- **Reference-image rotation** — changing the image factor without re-embedding. Back-burner, not cancelled. +- **Per-entry subkeys** — no real-world benefit at family-vault scale; see design rationale in `docs/ARCHITECTURE.md`. +- **libgit2 / gitoxide** — shell-out to `git` is intentional; see `crates/relicario-cli/ARCHITECTURE.md`. diff --git a/STATUS.md b/STATUS.md new file mode 100644 index 0000000..3344a1f --- /dev/null +++ b/STATUS.md @@ -0,0 +1,56 @@ +# Relicario — Project Status + +> Update this file at the end of every dev iteration. It is the single source of truth for what is done, in progress, and next. + +## Version + +**Current tag:** v0.5.0 (2026-05-02) +**Active track:** v0.5.x UX polish + Plan B refactor continuation + +## What shipped in v0.5.0 (2026-05-02) + +Three release trains merged into one tag: + +**Security hardening (Plan A):** +- Pre-receive hook actually verifies signatures now — device-auth was a no-op before (S1) +- Backup-restore tar unpacking hardened against path traversal and zip-bomb (S2) +- `RELICARIO_*` env-var surface audited; `RELICARIO_NO_GROUPS_CACHE` gated to debug builds (S3) + +**Bug fixes:** +- Strength meter no longer goes stale after the regenerate button (B1) +- Snake_case error codes no longer leak into the UI (B2) + +**Features (originally v0.3.0 + v0.4.0):** +- `relicario backup export/restore` with `.relbak` format +- `relicario import lastpass` (LastPass CSV importer) +- Device authentication: ed25519 commit signing + Gitea deploy-key management +- Fullscreen UX Phase 1: visual foundation (sidebar + pane shell, dark theme) +- Fullscreen UX Phase 2A: smart inputs (password coloring, inline generator popover, custom-fields editor) + +## Recent work (post-v0.5.0, landed on main) + +**Plan B multi-stream refactor (2026-05-09 to present):** +- `prompt_or_flag` + builder compression — compressed `build_*_item` helpers (Stream A) +- `Vault::after_manifest_change` wrapper, single canonical `ParamsFile` in session (Stream B) +- Core/WASM seam: `base32_decode_lenient`, `parse_month_year`, `guess_mime` added to WASM exports; CLI parsers migrated to `relicario-core::parse` (Stream C) +- CLI: `gen` alias for `generate`, `-l`/`-w` short flags, batched purge +- `base32` module extracted from core, two duplicate RFC-4648 impls deduplicated +- License switched to GPL-3.0-or-later + +## In progress (uncommitted on main) + +- Vault lock screen logo (`extension/src/vault/vault.ts`) +- Vault container max-width constraint + list-pane width fix (`extension/src/vault/vault.css`) +- README name fix (Aaron D. Lee) + +## Up next + +1. **Phase 2B: form layout polish** — spacing, density, section headers, attachment previews + Spec: `docs/superpowers/specs/2026-05-02-phase-2b-form-layout-design.md` +2. **1C-γ: attachments + Document type** — attachment UI in popup + vault tab; Document item add/view/edit + Specs: `docs/superpowers/specs/2026-04-24-relicario-extension-1c-gamma{1,2}-design.md` +3. **Phase 3: vault-tab shell** — sidebar nav + command palette stub + Spec: `docs/superpowers/specs/2026-04-27-relicario-vault-tab-design.md` +4. **Trash & history UI** — trash view, item/field-history viewer in vault tab + +See `ROADMAP.md` for the longer arc.