- package.json homepage: github.com/avi/Keynctr -> git.atitlan.io/avi/Keynctr - README: title 'Nostr Feed Manager' -> 'Keynctr', resolve all [YOUR_FORGEJO_INSTANCE_URL]/<OWNER>/<REPO> placeholders with the real Forgejo URL, fix clone dir and packaged-binary name (nost-feed-manager -> keynectr), data dir default ~/.local/share/keynectr, refresh test counts (cargo 225+6 e2e, npm 139/19 files) and project layout (audit/bunker/feed/updates modules, signer/ dir, Feed+SignerMode screens) - PRODUCT.md: data dir corrected with migration note
47 lines
5.9 KiB
Markdown
47 lines
5.9 KiB
Markdown
# Product
|
|
|
|
<!-- impeccable:product-schema 1 -->
|
|
|
|
## Platform
|
|
web
|
|
|
|
## Users
|
|
Primary: Linux Nostr users (daily use) who manage one or more keypairs and need to publish securely without exposing secrets. Situation: at their Linux desktop (X11/Wayland), switching profiles, composing notes, managing relays, and approving NIP-46 signing requests from other apps.
|
|
|
|
Secondary/expanded: Newcomers creating their first Nostr identity via a friendly GUI. The product is progressive — zero-to-first-profile onboarding is frictionless, but the same vault scales to power workflows (multiple profiles, CLI, remote signer). Success means the user can create, select, and publish as any profile, keep keys encrypted at rest, and never feel forced to paste an `nsec` elsewhere.
|
|
|
|
## Product Purpose
|
|
Nostr Keynctr (Nostr Feed Manager) pairs a hardened Rust core with an Electron + React desktop shell so private keys stay under your control: in embedded/bunker modes they live only in the local encrypted vault, and in external-signer mode they never touch this machine at all. It makes self-custodied Nostr publishing practical: generate/switch profiles, compose with preview and rich attachments, publish with per-relay receipts, curate relays and feeds, and serve as a NIP-46 remote signer ("bunker") for other Nostr apps. Success is a trustworthy, local-first identity manager you can use daily, via GUI or the same Rust CLI.
|
|
|
|
## Positioning
|
|
**Keys under your control, in whichever mode you choose — and the architecture proves it.** In embedded/bunker modes the renderer never receives secret material: all key generation, signing, relay communication, and encryption happen inside the Rust backend over a JSON-lines IPC channel, with NIP-46 approval gating every external sign/decrypt request. In external-signer mode (Amber, hardware signer, remote bunker) no secret key is present on this machine at all — a stronger posture when the desktop itself is the thing you distrust, since a compromise of this machine cannot extract a key it never held. A neighboring app could copy features, but cannot truthfully copy this verifiable separation while offering the same dual CLI + GUI surface.
|
|
|
|
## Operating Context
|
|
Workflows: create/switch/delete/undo profiles, compose (Write/Preview, character count, up to 3 link previews, image pick → nostr.build upload with NIP-92 imeta), publish with per-relay receipts, feed aggregation (all vs. My contacts, 24h window), relay add/remove/enable/disable/test, NIP-05 assignment, secret reveal after unlock, vault backup, lock/unlock.
|
|
|
|
Environments: Linux desktop (Electron 33), Rust release backend (`target/release/keynectr serve` via stdio), Vite dev server optionally via `NOSTR_GUI_DEV_URL`. Data directory `~/.local/share/keynectr` (auto-migrated from the legacy `nost-feed-manager` dir; override `XDG_DATA_HOME`), vault `profiles_vault.json` (migrated from legacy Python CLI with timestamped backup), settings file alongside.
|
|
|
|
Rituals: single-click Approve/Reject for NIP-46 requests; explicit `window.confirm` for delete; 5s themed undo bar; publish confirmation toggle; per-relay status dots.
|
|
|
|
## Capabilities and Constraints
|
|
Capabilities: profile create/switch/rename/set-picture/set-nip05/publish metadata; note publish with image imeta + link cards; feed aggregation and contact filtering; relay management and latency test; encrypted vault (AES-256-GCM + Argon2id), lock/unlock, set/remove password, reveal secret (hex + nsec); NIP-46 bunker; settings (theme light/dark/glass/neon, confirm_before_publish, shorten_npub); vault backup; CLI parity via same Rust crate.
|
|
|
|
Constraints (durable): local-only vault — no cloud sync; secrets encrypted at rest, derived key in-memory only and zeroized on lock/drop; renderer never sees secrets; dialogs/HTTP/media handled in Electron main, not renderer; files 0600, dirs 0700; NIP-98 auth for uploads; passwords via `NFM_PASSWORD` or prompt, never CLI args; CSP (`app://` prod vs devserver).
|
|
|
|
Decisions left open: whether undo_history should preserve full `StoredProfile` (currently `ProfileSummary` → secret lost on undo); long-term packaging/distribution; relay defaults.
|
|
|
|
## Brand Commitments
|
|
Name: Nostr Keynctr / Nostr Feed Manager (early beta v0.1.0, MIT, Forgejo-hosted). Voice: friendly, security-explicit, no hype. Assets: `public/icon.png`, sidebar logo, `KeynectrAppIconPossibility02.jpeg` (untracked concept). No fabricated testimonials or benchmarks; existing copy in `README.md`, empty states, and settings descriptions is authoritative.
|
|
|
|
## Evidence on Hand
|
|
Real content: Rust crate (`src/app, vault, crypto, profiles, publish, relays, signer, feed`), React screens (`Compose, Home, Profiles, Relays, Settings, Signer`), `frontend/src/lib/types`, `AppProvider` context, `fakeBackend` Vitest suite (99 tests), `CHECKPOINT-encryption.md`. No marketing site or pricing; no external testimonials to preserve.
|
|
|
|
## Product Principles
|
|
1. **Keys under your control** — every feature must preserve the Rust/renderer boundary and approval gates (secrets never reach the GUI in local modes, and never reach this machine in external-signer mode); convenience never bypasses explicit consent.
|
|
2. **Local-first, verifiable** — encrypt at rest, least-privilege files, per-relay receipts, and auditable IPC over transient convenience.
|
|
3. **Progressive disclosure** — newcomer can succeed in two clicks; power user can stay in CLI or manage many profiles without UI churn.
|
|
4. **One core, two doors** — GUI and CLI remain interchangeable via the same Rust engine; no feature lives only in one surface without justification.
|
|
5. **Calm trust** — theming (light/dark/glass/neon) and microcopy earn confidence through precision, not loudness; undo and receipts make errors recoverable.
|
|
|
|
## Accessibility & Inclusion
|
|
Linux desktop accessibility baseline (keyboard-navigable, focus-visible `var(--focus)`, screen-reader roles on status/alerts). No product-specific a11y standard declared; future work should keep contrast per theme tokens and ensure dialogs are dismissible via keyboard.
|