docs(spec): doc-structure redesign — tour-shaped, topic-named, scope-pinned
Proposes renaming the three overlapping ARCHITECTURE.md files into topic-named docs (top-level → DESIGN.md, docs/ARCHITECTURE.md → docs/CRYPTO.md), moving FORMATS.md into docs/, and adding scope headers + "Next:" footers to every tour doc so the reading order is canonical: README → DESIGN → CRYPTO → FORMATS → SECURITY → per-crate ARCHITECTURE → extension/ARCHITECTURE. Direct response to the drift audit run earlier today (the audit's content fixes already landed in210232d,cf7478d,fa659eb). This spec attacks the structural causes: name collisions, no scope boundaries, no reading-order signposts, root/docs/ asymmetry. Migration is mechanical — 5 sequential commits, no content rewrites: rename, headers+footers, link-fixes, CLAUDE.md update, verification. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,245 @@
|
||||
# Doc Structure Redesign — Design
|
||||
|
||||
**Date:** 2026-05-30
|
||||
**Status:** Proposed
|
||||
**Source:** Drift audit run on this same date (three parallel agents over the living docs) + follow-up brainstorm with the user.
|
||||
**Effort estimate:** S (one focused afternoon — renames + headers + link-fixes, no content rewrites).
|
||||
|
||||
## Summary
|
||||
|
||||
The living docs split into roughly thirteen files spread across the repo root, `docs/`, `crates/*`, and `extension/`. Three of them are called `ARCHITECTURE.md` and overlap in scope, which is exactly where the drift audit clustered (top-level called `0x01` while code shipped `0x02`, `FORMATS.md` listed 16-hex AttachmentIds while code used 32, per-crate maps missed five public modules and several CLI commands). This design keeps the file count roughly the same but **renames docs by topic, pins each doc to an explicit scope, and chains them into a single reading order**. A contributor (or future-you after a long break) lands on `README`, gets walked through `DESIGN → docs/CRYPTO → docs/FORMATS → docs/SECURITY → crates/*/ARCHITECTURE.md → extension/ARCHITECTURE.md`, never sees two files with the same name, and never has to guess which doc owns a given fact.
|
||||
|
||||
The drift fixes themselves landed in three commits earlier today (`210232d`, `cf7478d`, `fa659eb`). This redesign attacks the *structural* causes of the drift so the next audit has less to find.
|
||||
|
||||
## Findings addressed
|
||||
|
||||
The drift audit produced a punch list across three themes. The structural causes this redesign attacks are:
|
||||
|
||||
- **Three files named `ARCHITECTURE.md` at three levels with overlapping scope.** Top-level vs `docs/ARCHITECTURE.md` overlap drove the `0x01`-vs-`0x02` divergence and the `MIN_COPIES` confusion. Renaming the top-level to `DESIGN.md` and the `docs/` one to `docs/CRYPTO.md` eliminates the name collision and makes each doc's topic obvious from its filename.
|
||||
- **No scope boundaries between docs.** When the wire-format byte changed in code, there was no rule saying "the version-byte diagram lives in `docs/CRYPTO.md`, not in `FORMATS.md` or `DESIGN.md`," so the diagrams in two docs drifted apart. Adding explicit scope headers to each tour doc makes "where does this fact go?" unambiguous.
|
||||
- **No reading order signposts.** A cold reader couldn't tell whether to start at README, top-level ARCHITECTURE, or `docs/ARCHITECTURE.md`. "Next:" footers on every tour doc make a single canonical path.
|
||||
- **`FORMATS.md` sitting at the repo root while every other reference doc sits in `docs/`.** Asymmetry adds cognitive load. Moving it to `docs/FORMATS.md` aligns with the rest.
|
||||
- **`CLAUDE.md`'s "Living docs — update discipline" table is the only place the scope-rules are written.** It lists *when* to update each doc but not *what each doc owns vs does not own*. The new scope headers act as on-doc enforcement; the CLAUDE.md table is updated to point at the new filenames and adds three new discipline rules.
|
||||
|
||||
Out of scope (intentionally): STATUS.md drift habit (a behavioural problem, not structural); per-crate `main.rs:NNNN` line-number citations going stale when handlers move (a habit nudge — cite by function name, not line — but cross-cutting and worth its own pass).
|
||||
|
||||
## Goals
|
||||
|
||||
- A cold reader can flow from `README → DESIGN → docs/CRYPTO → docs/FORMATS → docs/SECURITY → crates/*/ARCHITECTURE.md → extension/ARCHITECTURE.md` without ping-ponging or guessing which doc owns what.
|
||||
- Every tour doc declares its scope in a 1-2 sentence header at the top and points at the next doc in a single-line footer at the bottom.
|
||||
- The drift surface shrinks: no two docs claim to own the same fact.
|
||||
- Migration is mechanical (renames + header additions + link fixes); no content is rewritten. The drift audit already cleaned the content.
|
||||
|
||||
## Non-goals
|
||||
|
||||
- Renaming per-crate or extension `ARCHITECTURE.md` files. Their nesting (`crates/X/`, `extension/`) already disambiguates them.
|
||||
- Adding new ARCHITECTURE.md files for `relicario-server` or `relicario-wasm`. Both crates are small enough that a per-crate doc would be more maintenance than help. Add later if either grows.
|
||||
- Touching `STATUS.md`, `ROADMAP.md`, `CHANGELOG.md`. Their roles are well-defined and the audit found no structural issue there.
|
||||
- Touching `docs/superpowers/specs/` or `docs/superpowers/plans/`. Intentionally accumulating.
|
||||
- Adding `CONTRIBUTING.md`. The "me + Claude, contributor-ready" audience choice means we keep the docs welcoming but don't bolt on contributor-onboarding pages we don't need yet.
|
||||
|
||||
## Target structure
|
||||
|
||||
```
|
||||
README.md Front door (already great). Trim its mid-section
|
||||
"Architecture" stub to a one-paragraph pointer at
|
||||
DESIGN.md. Pitch + security model + quick-start +
|
||||
reference image + recovery + roadmap teaser stay.
|
||||
|
||||
DESIGN.md NEW NAME (replaces top-level ARCHITECTURE.md).
|
||||
The system tour: four codebases, contracts between
|
||||
them, secrets map, build matrix, global code-map index.
|
||||
|
||||
docs/
|
||||
├── CRYPTO.md NEW NAME (renamed from docs/ARCHITECTURE.md).
|
||||
│ Crypto pipeline + vault flows + DCT embedding +
|
||||
│ high-level encrypted-file-format diagram.
|
||||
│
|
||||
├── FORMATS.md MOVED from repo root.
|
||||
│ Wire formats: .enc blob layout, params.json,
|
||||
│ devices.json, manifest schema, .relbak envelope,
|
||||
│ ID formats, settings JSON schema.
|
||||
│
|
||||
└── SECURITY.md UNCHANGED LOCATION.
|
||||
Threat model, attacker scenarios, device auth,
|
||||
env-var trust surface.
|
||||
|
||||
crates/
|
||||
├── relicario-core/ARCHITECTURE.md UNCHANGED (nesting disambiguates).
|
||||
├── relicario-cli/ARCHITECTURE.md UNCHANGED.
|
||||
├── relicario-server/ No doc — too small.
|
||||
└── relicario-wasm/ No doc — too small.
|
||||
|
||||
extension/ARCHITECTURE.md UNCHANGED.
|
||||
|
||||
(unchanged: STATUS / ROADMAP / CHANGELOG / CLAUDE / LICENSE / docs/superpowers/)
|
||||
```
|
||||
|
||||
**Reading order:**
|
||||
|
||||
```
|
||||
README → DESIGN → docs/CRYPTO → docs/FORMATS → docs/SECURITY
|
||||
→ crates/relicario-core/ARCHITECTURE.md
|
||||
→ crates/relicario-cli/ARCHITECTURE.md
|
||||
→ extension/ARCHITECTURE.md
|
||||
```
|
||||
|
||||
Realized by two conventions on every tour doc:
|
||||
|
||||
1. **Scope header (top, 1-2 sentences):** *"This doc owns X. See Y for Z."*
|
||||
2. **"Next:" footer:** a one-line pointer to the next doc in the tour.
|
||||
|
||||
## Per-file scope definitions
|
||||
|
||||
The exact scope headers + "Next:" footers to be pasted at the top and bottom of each tour doc.
|
||||
|
||||
### `README.md`
|
||||
|
||||
> **Audience:** users + evaluators. This doc owns the pitch, security-model summary, quick-start commands, reference-image explanation, recovery-QR overview, and roadmap teaser. Goes no deeper — for the system tour see [DESIGN.md](DESIGN.md), for crypto see [docs/CRYPTO.md](docs/CRYPTO.md).
|
||||
|
||||
Existing-content delta: the current "Architecture" section gets trimmed to one paragraph pointing at `DESIGN.md`. Quick start / Reference image / Recovery / Roadmap sections stay.
|
||||
|
||||
Footer: `Next: [DESIGN.md](DESIGN.md) — the system tour.`
|
||||
|
||||
### `DESIGN.md` *(new name; replaces top-level `ARCHITECTURE.md`)*
|
||||
|
||||
> **Audience:** anyone wanting to understand the system at the cross-codebase level. This doc owns the four-codebase map, inter-codebase contracts, the secrets map (what secret lives where), the build matrix, and the global code-map index. **Does NOT own:** crypto pipeline details (see `docs/CRYPTO.md`), wire formats (see `docs/FORMATS.md`), threat model (see `docs/SECURITY.md`), per-crate module maps (see `crates/*/ARCHITECTURE.md` and `extension/ARCHITECTURE.md`).
|
||||
|
||||
Footer: `Next: [docs/CRYPTO.md](docs/CRYPTO.md) — the crypto pipeline that backs this design.`
|
||||
|
||||
### `docs/CRYPTO.md` *(new name; renamed from `docs/ARCHITECTURE.md`)*
|
||||
|
||||
> **Audience:** anyone evaluating or auditing the crypto. This doc owns Argon2id parameters and rationale, XChaCha20-Poly1305 rationale, vault creation/unlock flow diagrams, DCT-steganography embed and extract flows, and the high-level encrypted-file-format diagram. **Does NOT own:** byte-level schemas or JSON shapes (see `docs/FORMATS.md`), attacker scenarios (see `docs/SECURITY.md`), or per-module crypto implementation (see `crates/relicario-core/ARCHITECTURE.md`).
|
||||
|
||||
Footer: `Next: [FORMATS.md](FORMATS.md) — the byte-level wire formats.`
|
||||
|
||||
### `docs/FORMATS.md` *(moved from repo root)*
|
||||
|
||||
> **Audience:** anyone implementing a compatible client or reading raw vault bytes. This doc owns the `.enc` blob layout, `params.json` / `salt` / `devices.json` / `revoked.json` shapes, the manifest JSON schema, the `.relbak` envelope, item-ID formats, and the settings JSON schema. **Does NOT own:** why these formats look this way (see `docs/CRYPTO.md`), threat model around them (see `docs/SECURITY.md`), or Rust struct internals (see `crates/relicario-core/ARCHITECTURE.md`).
|
||||
|
||||
Footer: `Next: [SECURITY.md](SECURITY.md) — the threat model.`
|
||||
|
||||
### `docs/SECURITY.md` *(unchanged location)*
|
||||
|
||||
> **Audience:** auditors and curious users. This doc owns the threat model, attacker-scenarios table, device-authentication model, env-var trust surface, and known limitations. **Does NOT own:** crypto primitive details (see `docs/CRYPTO.md`), wire formats (see `docs/FORMATS.md`), or implementation (see `crates/*/ARCHITECTURE.md`).
|
||||
|
||||
Footer: `Next: [../crates/relicario-core/ARCHITECTURE.md](../crates/relicario-core/ARCHITECTURE.md) — implementation, starting with the platform-agnostic core.`
|
||||
|
||||
### `crates/relicario-core/ARCHITECTURE.md`
|
||||
|
||||
> **Audience:** contributors editing or extending `relicario-core`. This doc owns the module map for this crate, module-level invariants (e.g., no filesystem, no network), key flows at the module level, and the crate's test architecture. **Does NOT own:** crypto primitives or threat model (see `docs/CRYPTO.md`, `docs/SECURITY.md`), wire formats (see `docs/FORMATS.md`).
|
||||
|
||||
Footer: `Next: [../relicario-cli/ARCHITECTURE.md](../relicario-cli/ARCHITECTURE.md) — how the CLI wraps the core.`
|
||||
|
||||
### `crates/relicario-cli/ARCHITECTURE.md`
|
||||
|
||||
> **Audience:** contributors editing the CLI. This doc owns the CLI module map, the clap command surface, per-command key flows, session/unlock semantics, and helpers. **Does NOT own:** crypto, wire formats, or threat model (see `docs/`).
|
||||
|
||||
Footer: `Next: [../../extension/ARCHITECTURE.md](../../extension/ARCHITECTURE.md) — the browser-side surface.`
|
||||
|
||||
### `extension/ARCHITECTURE.md`
|
||||
|
||||
> **Audience:** contributors editing the browser extension. This doc owns the bundle structure (popup, vault tab, background SW, content scripts), the SW ↔ popup message contract, the component / pane architecture, routing, and the build pipeline. **Does NOT own:** WASM crypto internals (see `crates/relicario-core/ARCHITECTURE.md`), wire formats (see `docs/FORMATS.md`), or threat model (see `docs/SECURITY.md`).
|
||||
|
||||
Footer: `End of tour. For roadmap and in-flight work see [../STATUS.md](../STATUS.md) and [../ROADMAP.md](../ROADMAP.md).`
|
||||
|
||||
## Migration
|
||||
|
||||
Five sequential commits. Each is mechanical; no content is rewritten.
|
||||
|
||||
### Commit 1 — Renames
|
||||
|
||||
```bash
|
||||
git mv ARCHITECTURE.md DESIGN.md
|
||||
git mv docs/ARCHITECTURE.md docs/CRYPTO.md
|
||||
git mv FORMATS.md docs/FORMATS.md
|
||||
```
|
||||
|
||||
No content changes. Git tracks the renames so `git blame` / `git log --follow` survive.
|
||||
|
||||
### Commit 2 — Scope headers + "Next:" footers on the eight tour docs
|
||||
|
||||
Add the headers and footers verbatim as listed in the **Per-file scope definitions** section above. Also trim `README.md`'s current "Architecture" section to a one-paragraph pointer at `DESIGN.md` in the same commit.
|
||||
|
||||
### Commit 3 — Fix incoming links to old paths
|
||||
|
||||
Greppable list of paths to update:
|
||||
|
||||
| Old path | New path |
|
||||
|---|---|
|
||||
| `ARCHITECTURE.md` (top-level reference) | `DESIGN.md` |
|
||||
| `docs/ARCHITECTURE.md` | `docs/CRYPTO.md` |
|
||||
| `FORMATS.md` (top-level reference) | `docs/FORMATS.md` |
|
||||
|
||||
Known callsites to update:
|
||||
|
||||
- `CLAUDE.md` — the "Living docs — update discipline" table + the "Planning & design specs" core-references list.
|
||||
- `README.md` — the architecture tree on line ~160 shows `docs/architecture/` which doesn't exist; fix in this pass.
|
||||
- `crates/*/ARCHITECTURE.md` and `extension/ARCHITECTURE.md` — cross-references to top-level ARCHITECTURE.md or FORMATS.md.
|
||||
- `docs/superpowers/specs/*.md` — some specs reference the old paths; update those whose specs are still load-bearing.
|
||||
|
||||
Verification command (run before this commit):
|
||||
|
||||
```bash
|
||||
grep -rn --include='*.md' -E '(\bARCHITECTURE\.md\b|\bdocs/ARCHITECTURE\.md\b|\b/FORMATS\.md\b|^FORMATS\.md\b)' . \
|
||||
| grep -v docs/superpowers/test-runs/ \
|
||||
| grep -v docs/superpowers/audits/
|
||||
```
|
||||
|
||||
The grep should return zero matches after this commit (modulo intentional references in audit / test-run history, which we leave alone).
|
||||
|
||||
### Commit 4 — Update `CLAUDE.md`
|
||||
|
||||
Two changes to `CLAUDE.md`:
|
||||
|
||||
1. Update the "Living docs — update discipline" table with the new filenames (`DESIGN.md`, `docs/CRYPTO.md`, `docs/FORMATS.md`).
|
||||
2. Add three new rules (see **Maintenance discipline** below).
|
||||
3. Update the "Planning & design specs" core-references list to point at `docs/CRYPTO.md` / `docs/FORMATS.md` if it currently points elsewhere.
|
||||
|
||||
### Commit 5 — Verification
|
||||
|
||||
A read-through commit (no content changes; this is just where we confirm the work). The verification checklist in the **Verification** section below runs cleanly. If it doesn't, fix and amend the relevant commit.
|
||||
|
||||
## Maintenance discipline
|
||||
|
||||
Three rules added to `CLAUDE.md` to prevent the kind of drift the audit found:
|
||||
|
||||
1. **Scope-boundary check.** When editing a tour doc, verify the change fits the doc's scope header. If it doesn't, the change belongs in a different doc — move it instead of stretching the scope. (Concretely: a sentence about crypto added to `DESIGN.md` belongs in `docs/CRYPTO.md`; a wire-format table added to `docs/CRYPTO.md` belongs in `docs/FORMATS.md`.)
|
||||
|
||||
2. **Code-constant pinning.** When a tour doc cites a code constant (`VERSION_BYTE = 0x02`, `QUANT_STEP = 50.0`, `MIN_COPIES = 5`, `MANIFEST_SCHEMA_VERSION = 2`, etc.), the doc must cite the source file + line. When the underlying constant changes, grep for the citation pattern and update the docs together with the code change in the same commit. Most of the drift the audit found was code-constant drift; this rule attacks it at the source.
|
||||
|
||||
3. **New-doc rule.** When adding a tour doc, also update (a) `DESIGN.md`'s code-map, (b) the reading-order sequence (the "Next:" footer chain), and (c) the `CLAUDE.md` living-docs table. A new doc that doesn't appear in all three is not done.
|
||||
|
||||
## Verification
|
||||
|
||||
Run as part of Commit 5. All checks must pass.
|
||||
|
||||
1. **Scope-header presence.** Every tour doc (`README`, `DESIGN`, `docs/CRYPTO`, `docs/FORMATS`, `docs/SECURITY`, `crates/relicario-core/ARCHITECTURE`, `crates/relicario-cli/ARCHITECTURE`, `extension/ARCHITECTURE`) has its scope header at the top, matching the wording in this spec.
|
||||
|
||||
2. **"Next:" footer chain.** Each tour doc except `extension/ARCHITECTURE.md` ends with a `Next:` footer pointing at the next doc in the canonical order. `extension/ARCHITECTURE.md` ends with the "End of tour" pointer at STATUS/ROADMAP.
|
||||
|
||||
3. **No broken links.** Every link in every tour doc resolves to an existing file. Verified with a markdown link checker or by hand-grepping for `](./` / `](../` references and confirming the target exists.
|
||||
|
||||
4. **No old paths remain.** The grep in Commit 3 returns zero matches outside `docs/superpowers/test-runs/` and `docs/superpowers/audits/`.
|
||||
|
||||
5. **`CLAUDE.md` table is current.** The "Living docs — update discipline" table lists the new filenames; the three new discipline rules are present.
|
||||
|
||||
6. **Renames are git-tracked.** `git log --follow DESIGN.md` shows history continuous from the old `ARCHITECTURE.md`. Same for `docs/CRYPTO.md` and `docs/FORMATS.md`.
|
||||
|
||||
7. **README architecture section trimmed.** `README.md`'s mid-section "Architecture" is at most one paragraph and points at `DESIGN.md`.
|
||||
|
||||
## Out-of-scope safeties
|
||||
|
||||
Things this design intentionally does *not* address; flagging for honesty:
|
||||
|
||||
- **STATUS.md drift habit** (shipped work lingering as "in progress"): a behavioural issue, not structural. The audit caught it; the fix was manual. A future pass might add a release-checklist hook or a pre-tag CI gate.
|
||||
- **Per-crate `ARCHITECTURE.md` line-citation drift** (e.g., `main.rs:NNNN` references stale after handlers moved into `commands/`): partially addressed by rule 2 (code-constant pinning), but not fully. A future habit nudge — cite by function name, not by line number — is worth landing later but is cross-cutting and out of scope here.
|
||||
- **`docs/superpowers/specs/` and `plans/` accumulation**: intentional. Not touched.
|
||||
|
||||
## Footnote — alternative approaches considered
|
||||
|
||||
Three approaches were brainstormed before settling on this design (full details in the conversation that produced this spec, archived nowhere because that's how brainstorms work):
|
||||
|
||||
- **Approach B — README expands; supporting docs collapse.** Fold the top-level `ARCHITECTURE.md` and `docs/ARCHITECTURE.md` into one big doc (or into README). Rejected: the combined doc gets long, and "organic flow" suffers when one doc covers from quick-start to crypto pipeline to module boundaries. README starts to do too much.
|
||||
- **Approach C — Keep current files, add reading paths.** Add a top-level `READING-ORDER.md` and grow scope headers on each existing doc. Rejected: doesn't fix the three-files-named-`ARCHITECTURE.md` cognitive cost. The drift surface stays the same; we just navigate it better.
|
||||
- **Approach A — Tour-shaped + topic-named** *(chosen).* Filenames carry meaning, linear flow is unambiguous, drift surface shrinks by killing the 3× `ARCHITECTURE.md` overload.
|
||||
Reference in New Issue
Block a user