Extends the Block 2 spike to attack the highest-risk unbuilt piece (private
messaging) and to prove the Q2 architecture recommendation with running code:
- NostrConnection: one shared socket+key+sign+REQ/EOSE lifecycle. Refactored
NostrOfferTransport onto it; added NostrMessageTransport — two thin contracts
on ONE connection (the 'one connection, three interfaces' shape).
- NIP-44 v2 encryption (secp256k1 ECDH -> ChaCha20 + HMAC, length-hiding pad).
- NIP-17/NIP-59 gift-wrap: rumor(14) -> seal(13) -> wrap(1059, ephemeral key).
Alice->Bob DM round-trips through the relay: encrypted, sender authenticated,
and metadata-private (relay/eavesdropper sees only ciphertext, an ephemeral
author and the recipient p-tag — Alice stays hidden).
Findings updated: NIP-17 risk drops Medium-High -> Medium (hardening, not
feasibility); next de-risking target is the web of trust. NIP-44 not yet
vector-verified (noted). 20 tests green, analyzer clean, Block 1 untouched.
Throwaway research spike (spike/ branch, outside pub workspace, no prod deps
touched). Validates the open Block 2 decisions before committing a funded round:
1. Deterministic one-way secp256k1 (Nostr) key derived from the Ğ1 root seed
via HKDF — user still backs up ONE thing. Reproducible + signs (BIP340).
2. OfferTransport abstraction over Nostr NIP-99 (kind 30402); Offer stays
inventory/location-agnostic, geohash coarsened on the wire (tested).
3. publish->discover-by-geohash proven end-to-end against an in-process
hermetic mini-relay (~34ms round-trip).
Findings + risks + recommendation in docs/design/spike-block2-findings.md.
Block 1 suite untouched. 14 tests green, analyzer clean.
Interchange export/import for Phase 1 (data-model §7):
- JSON: canonical, versioned envelope (formatVersion 1) with all sync
metadata verbatim, photos embedded as base64, tombstones excluded.
Species are re-resolved on import by scientific name (catalog ids are
per-install). Reader tolerates unknown fields/enum values (§5.2) and
rejects newer format versions with a clear error.
- CSV: export-only spreadsheet flatten, one row per lot, RFC 4180
escaping, never any photo bytes.
- Import merges by UUIDv7 id in one transaction: insert-if-unknown
preserving original stamps, last-writer-wins by packed HLC for known
mutable rows, append-only movements; afterwards the local clock
receiveEvent()s the newest imported stamp so it never runs behind.
- Settings gains a Backup section (export CSV/JSON, import JSON with
confirmation); file dialogs behind a FileService interface backed by
file_picker (MIT).
- Tests: codec round-trip and tolerance, reconciler LWW, repository
export→import round-trip (fresh DB, idempotent re-import, newer-local
wins, clock monotonicity, species re-resolution), backup widget flows.
Expand LotType from {seed, plant} to six append-only forms (seed,
seedling, plant, tree, bulb, cutting) and add an optional Presentation
attribute (pot/tray/plug/bareRoot/rootBall) kept separate from quantity
so 'how many' and 'in what packaging' never conflate.
Add attachments.sortOrder so the cover photo is the lowest-ordered one,
enabling reordering from the full-screen viewer. Expand QuantityKind
with the new plant-aware forms.
Migrations are additive (v1→v5 all covered by migration_test); enum
values are stored by name and appended only, keeping CRDT sync safe.
Visual pass toward docs/mockups (06 inventory, 07 item):
- Bundle the seedks icon font (chars a–k → seed pictograms: jar, packet, spoon…)
and a SeedGlyph/QuantityKindIcon helper.
- Green app bar + pale-green canvas theme (buildTaneTheme).
- Inventory list: rounded-square photo thumbnail or green initial avatar, bold
title, scientific-name subtitle, trailing edit pencil, styled category
headers, rounded search field, seed-glyph empty state.
- Quantity selectors (quick-add + add-lot) show the seed pictogram + word;
detail lot lines use the kind's glyph.
- Detail header restyled to mockup 07: category link + scientific name on the
left, photo on the right.
watchInventory now also returns the linked species' scientific name (subtitle).
37 app tests green; seedks font verified in the Linux asset bundle.