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 <noreply@anthropic.com>
This commit is contained in:
15
CLAUDE.md
15
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`.
|
||||
|
||||
102
FORMATS.md
Normal file
102
FORMATS.md
Normal file
@@ -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/<id>.enc`, `attachments/<item-id>/<aid>.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": "<hex-encoded ed25519 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": "<hex>", "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`.
|
||||
54
ROADMAP.md
Normal file
54
ROADMAP.md
Normal file
@@ -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`.
|
||||
56
STATUS.md
Normal file
56
STATUS.md
Normal file
@@ -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<T>` + 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.
|
||||
Reference in New Issue
Block a user