docs: add language glossary, QFD design, and ADRs
Capture the walk-with-me + qfd session: CONTEXT.md ubiquitous-language glossary, DESIGN.md goal-driven cascade (Beauty / Pride & Peace / public voice), and ADRs for Note identity (Path) and the two reference modes (Live vs Snapshot).
This commit is contained in:
15
docs/adr/0001-note-identity-is-path.md
Normal file
15
docs/adr/0001-note-identity-is-path.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Note identity is Path, not SHA
|
||||
|
||||
A **Note**'s stable identity is its **Path** (its location in the repo, e.g. `ideas/zettel.md`), not its content **SHA**. We decided this because authors link to Notes by path (markdown `[[…]]` resolved via `resolvePath()`) and expect those links to survive edits — whereas a Note's SHA changes on every edit.
|
||||
|
||||
This is surprising in the current code, which keys **Backlinks** (`Backlink { sha }`) and the stacked-notes URL (`?stackedNotes=sha1;sha2`) by SHA. Those are runtime *handles* that must resolve *through* the Path; if a SHA-handle ever disagrees with the Path, the Path wins.
|
||||
|
||||
## Considered options
|
||||
|
||||
- **Path as identity (chosen).** Survives edits; matches how authors write links. Cost: needs a resolution layer mapping Path → current SHA for lookup/navigation, and the SHA-keyed code is a known fragility to reconcile.
|
||||
- **SHA as identity (rejected).** Matches the current code literally and needs no resolution layer, but every edit produces a new identity — backlinks and open-note URLs would break on edit. Unacceptable for a notes app where editing is routine.
|
||||
|
||||
## Consequences
|
||||
|
||||
- Backlinks and stacked-note navigation should ultimately be expressed in terms of Path; SHA-keying stays only as an internal lookup handle.
|
||||
- Caching by SHA remains valid (it is content-addressed versioning), but Note identity must never be conflated with it.
|
||||
20
docs/adr/0002-two-reference-modes.md
Normal file
20
docs/adr/0002-two-reference-modes.md
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
status: accepted (refines ADR-0001)
|
||||
---
|
||||
|
||||
# Two reference modes: Live (Path) and Snapshot (SHA)
|
||||
|
||||
A reference to a Note resolves in one of two deliberate modes. A **Live reference** (by **Path**) resolves to the Note's *current* content — this is a Backlink you follow in your own repo, and it reflects edits (Note identity = Path, per ADR-0001). A **Snapshot reference** (by **SHA**) resolves to that *exact, immutable* version — this is a shared or bookmarked stack link (`?stackedNotes=sha`), content-addressed so what was shared cannot change underneath a reader.
|
||||
|
||||
This refines ADR-0001, which framed SHA-keyed references as "a fragility." That framing was too absolute: SHA-pinning is the **correct** tool for a Snapshot reference. Pinning is an *integrity* feature — it guarantees a shared view can't be silently rewritten, so no reader is misled and no author is misrepresented.
|
||||
|
||||
## Considered options
|
||||
|
||||
- **Two explicit modes (chosen).** Live=Path, Snapshot=SHA, each with a clear purpose. Cost: the resolver must support both, and the UI must make the mode legible (you should know whether you're reading "now" or "as shared").
|
||||
- **Single mode, Path only (rejected).** Simpler, but a shared link would always re-resolve to current content — destroying the integrity guarantee that makes sharing safe.
|
||||
- **Single mode, SHA only (rejected by ADR-0001).** In-repo navigation would break on every edit.
|
||||
|
||||
## Consequences
|
||||
|
||||
- The system **pre-caches** aggressively (content is cached by both SHA and Path on every fetch / freshness pull) so the pinned version is usually present, including offline.
|
||||
- When a Snapshot reference's pinned content is genuinely unavailable (never-fetched + offline — common on a flaky mobile connection), the system **falls back to the most up-to-date cached version and shows a banner** disclosing "this is the latest available, not the exact shared version." Integrity is preserved by **disclosure, not refusal**: the reader is never silently shown different content, but is also never dead-ended on the metro. (This chooses graceful continuity over a hard "unavailable" stop, given mobile is the primary read context.)
|
||||
Reference in New Issue
Block a user