2 Commits

Author SHA1 Message Date
adlee-was-taken
2de250a41e docs: promote overview.md to root ARCHITECTURE.md + add update discipline table
Move docs/architecture/overview.md to ARCHITECTURE.md at the repo root —
it is the primary cross-codebase architecture doc (four-codebase diagram,
inter-codebase contracts, secrets map, build matrix, test strategy, where-to-look
table) and belongs at the root alongside STATUS.md, ROADMAP.md, etc.

Update relative paths inside the file (../../crates/ → crates/, etc.).
Update CHANGELOG.md's one active reference to the old path.

Add a "Living docs — update discipline" table to CLAUDE.md that maps every
ALLCAPS.md file to the area it covers and the trigger for updating it. This
closes the loop on the ALLCAPS.md documentation system.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 19:44:30 -04:00
adlee-was-taken
1758edd5c8 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>
2026-05-15 19:44:30 -04:00
6 changed files with 246 additions and 12 deletions

View File

@@ -4,9 +4,9 @@ This is the cross-codebase entry point. It describes how the four Relicario code
> If you are about to make a change in a single codebase, read its `ARCHITECTURE.md` first: > If you are about to make a change in a single codebase, read its `ARCHITECTURE.md` first:
> >
> - [crates/relicario-core/ARCHITECTURE.md](../../crates/relicario-core/ARCHITECTURE.md) > - [crates/relicario-core/ARCHITECTURE.md](crates/relicario-core/ARCHITECTURE.md)
> - [crates/relicario-cli/ARCHITECTURE.md](../../crates/relicario-cli/ARCHITECTURE.md) > - [crates/relicario-cli/ARCHITECTURE.md](crates/relicario-cli/ARCHITECTURE.md)
> - [extension/ARCHITECTURE.md](../../extension/ARCHITECTURE.md) > - [extension/ARCHITECTURE.md](extension/ARCHITECTURE.md)
> >
> If you want historical *why*, see `docs/superpowers/specs/` — those are time-stamped decision artifacts. This overview describes what *is*. > If you want historical *why*, see `docs/superpowers/specs/` — those are time-stamped decision artifacts. This overview describes what *is*.
@@ -196,10 +196,10 @@ Core tests use **fast Argon2id params** (m=256, t=1, p=1) so they don't take for
| If you're working on... | Start with | | If you're working on... | Start with |
|---|---| |---|---|
| Crypto, item types, manifest format | [`crates/relicario-core/ARCHITECTURE.md`](../../crates/relicario-core/ARCHITECTURE.md) | | Crypto, item types, manifest format | [`crates/relicario-core/ARCHITECTURE.md`](crates/relicario-core/ARCHITECTURE.md) |
| A new CLI command or a CLI bug | [`crates/relicario-cli/ARCHITECTURE.md`](../../crates/relicario-cli/ARCHITECTURE.md) | | A new CLI command or a CLI bug | [`crates/relicario-cli/ARCHITECTURE.md`](crates/relicario-cli/ARCHITECTURE.md) |
| A new popup view, vault tab feature, or autofill change | [`extension/ARCHITECTURE.md`](../../extension/ARCHITECTURE.md) | | A new popup view, vault tab feature, or autofill change | [`extension/ARCHITECTURE.md`](extension/ARCHITECTURE.md) |
| A new SW message type | `extension/src/shared/messages.ts` (capability sets), then [`extension/ARCHITECTURE.md § Invariants`](../../extension/ARCHITECTURE.md) | | A new SW message type | `extension/src/shared/messages.ts` (capability sets), then [`extension/ARCHITECTURE.md § Invariants`](extension/ARCHITECTURE.md) |
| A new GitHost (e.g. GitLab support) | `extension/src/service-worker/git-host.ts` (interface) and existing implementations | | A new GitHost (e.g. GitLab support) | `extension/src/service-worker/git-host.ts` (interface) and existing implementations |
| The pre-receive hook / device-auth enforcement | `crates/relicario-server/src/main.rs`, then `docs/superpowers/specs/2026-05-02-device-authentication-design.md` for rationale | | The pre-receive hook / device-auth enforcement | `crates/relicario-server/src/main.rs`, then `docs/superpowers/specs/2026-05-02-device-authentication-design.md` for rationale |
| Adding a new item type | core's `item_types/` mod, then CLI's `build_*_item`/`edit_*` helpers, then extension's `popup/components/types/<type>.ts` | | Adding a new item type | core's `item_types/` mod, then CLI's `build_*_item`/`edit_*` helpers, then extension's `popup/components/types/<type>.ts` |

View File

@@ -135,7 +135,7 @@ two confirmed bugs).
the `.form-grid` cards above. Removes the visual rhythm break at the the `.form-grid` cards above. Removes the visual rhythm break at the
2-col → full-width transition. The popup surface is unchanged. 2-col → full-width transition. The popup surface is unchanged.
- **Documentation refreshed for v0.5.0 (doc audit, 14 findings).** - **Documentation refreshed for v0.5.0 (doc audit, 14 findings).**
`docs/architecture/overview.md` now describes four codebases (the `ARCHITECTURE.md` now describes four codebases (the
`relicario-server` pre-receive hook crate is no longer invisible); `relicario-server` pre-receive hook crate is no longer invisible);
`CLAUDE.md` project tree and roadmap reflect current state; `CLAUDE.md` project tree and roadmap reflect current state;
`docs/SECURITY.md` names the server crate and its `verify-commit` / `docs/SECURITY.md` names the server crate and its `verify-commit` /

View File

@@ -86,10 +86,32 @@ passphrase (UTF-8 bytes) || image_secret (32 bytes from reference JPEG)
Source code: `ssh://git@git.adlee.work:2222/alee/relicario.git` 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. Update the component `ARCHITECTURE.md` for any area you changed (see table below).
## Roadmap & status
Current in-flight work: `STATUS.md`. Full roadmap with release targets: `ROADMAP.md`. Wire format reference: `FORMATS.md`.
## Living docs — update discipline
| File | What it documents | Update when... |
|---|---|---|
| `ARCHITECTURE.md` | Cross-codebase structure: four codebases, contracts, secrets map, build matrix, test strategy | Adding a codebase, changing inter-codebase contracts, new build targets |
| `docs/ARCHITECTURE.md` | Crypto pipeline diagrams, vault creation/unlock flows, DCT embedding, encrypted file format | Changing crypto primitives, format version byte, or file format |
| `crates/relicario-core/ARCHITECTURE.md` | Module map, invariants, key flows, test architecture for `relicario-core` | Adding/changing modules, item types, or crypto invariants in core |
| `crates/relicario-cli/ARCHITECTURE.md` | Module map, invariants, key flows (init, unlock, all commands) for `relicario-cli` | Adding/changing CLI commands, helpers, or session behavior |
| `extension/ARCHITECTURE.md` | Bundle structure, SW↔popup contract, component architecture | Adding bundles, changing the SW message protocol, or major UI flows |
| `docs/SECURITY.md` | Threat model, device auth, env-var trust surface | Adding env vars, changing auth model, new security-relevant config |
| `FORMATS.md` | Wire formats: `.enc` blobs, `params.json`, `devices.json`, manifest schema | Changing any serialized format, version number, or on-disk layout |
| `STATUS.md` | In-flight work, recent landings, what's next | End of every dev iteration |
| `ROADMAP.md` | Full roadmap with release targets | When milestones shift or new work is scoped |
| `CHANGELOG.md` | User-facing release history | When tagging a release |

102
FORMATS.md Normal file
View 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
View 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
View 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.