# SeedPGP - Gemini Code Assist Project Brief

## Project Overview

**SeedPGP v1.4.7**: Client-side BIP39 mnemonic encryption webapp
**Stack**: Bun + Vite + React + TypeScript + OpenPGP.js + Tailwind CSS  
**Deploy**: Cloudflare Pages (private repo: `seedpgp-web`)  
**Live URL**: <https://seedpgp-web.pages.dev/>

## Core Constraints

1. **Security-first**: Never persist secrets (mnemonic/passphrase/private keys) to localStorage/sessionStorage/IndexedDB
2. **Small PRs**: Max 1-5 files per feature; propose plan before coding
3. **Client-side only**: No backend; all crypto runs in browser (Web Crypto API + OpenPGP.js)
4. **Honest security claims**: Don't overclaim what client-side JS can guarantee

## Non-Negotiables

- Small diffs only: one feature slice per PR (1-5 files if possible)
- No big code dumps; propose plan first, then implement
- Never persist secrets to browser storage
- Prefer "explain what you found in the repo" over guessing
- TypeScript strict mode; no `any` types without justification

---

## Architecture Map

### Entry Points

- `src/main.tsx` → `src/App.tsx` (main application)
- Build output: `dist/`

### Directory Structure

```BASH
src/
├── components/        # React UI components
│   ├── PgpKeyInput.tsx
│   ├── QrDisplay.tsx
│   ├── QrScanner.tsx
│   ├── ReadOnly.tsx
│   ├── StorageIndicator.tsx
│   ├── SecurityWarnings.tsx
│   └── ClipboardTracker.tsx
├── lib/              # Core logic & crypto utilities
│   ├── seedpgp.ts    # Main encrypt/decrypt functions
│   ├── sessionCrypto.ts  # Ephemeral AES-GCM session keys
│   ├── types.ts      # TypeScript interfaces
│   └── qr.ts         # QR code utilities
├── App.tsx           # Main app component
└── main.tsx          # React entry point
```

### Key Modules

#### `src/lib/seedpgp.ts`

Core encryption/decryption:

- `encryptToSeedPgp()` - Encrypts mnemonic with PGP public key + optional password
- `decryptFromSeedPgp()` - Decrypts with PGP private key + optional password
- Uses OpenPGP.js for PGP operations
- Output format: `SEEDPGP1:version:base64data:fingerprint`

#### `src/lib/sessionCrypto.ts` (v1.3.0+)

Ephemeral session-key encryption:

- `getSessionKey()` - Generates/returns non-exportable AES-GCM-256 key (idempotent)
- `encryptJsonToBlob(obj)` - Encrypts to `{v, alg, iv_b64, ct_b64}`
- `decryptBlobToJson(blob)` - Decrypts back to original object
- `destroySessionKey()` - Drops key reference for garbage collection
- Test: `await window.runSessionCryptoTest()` (DEV only)

#### `src/lib/types.ts`

Core interfaces:

- `SeedPgpPlaintext` - Decrypted mnemonic data structure
- `SeedPgpCiphertext` - Encrypted payload structure
- `EncryptedBlob` - Session-key encrypted cache format

---

## Key Features

### v1.0 - Core Functionality

- **Backup**: Encrypt mnemonic with PGP public key + optional password → QR display
- **Restore**: Scan/paste QR → decrypt with private key → show mnemonic
- **PGP support**: Import public/private keys (.asc files or paste)

### v1.1 - QR Features

- **QR Display**: Generate QR codes from encrypted data
- **QR Scanner**: Camera + file upload (uses html5-qrcode library)

### v1.2 - Security Monitoring

- **Storage Indicator**: Real-time display of localStorage/sessionStorage contents
- **Security Warnings**: Context-aware alerts about browser memory limitations
- **Clipboard Tracker**: Monitor clipboard operations on sensitive fields
- **Read-only Mode**: Toggle to clear state + show CSP/build info

### v1.3-v1.4 - Session-Key Encryption

- **Ephemeral encryption**: AES-GCM-256 session key (non-exportable) encrypts sensitive state
- **Backup flow (v1.3)**: Mnemonic auto-clears immediately after QR generation
- **Restore flow (v1.4)**: Decrypted mnemonic auto-clears after 10 seconds + manual Hide button
- **Encrypted cache**: Only ciphertext stored in React state; key lives in memory only
- **Lock/Clear**: Manual cleanup destroys session key + clears all state
- **Lifecycle**: Session key auto-destroyed on page close/refresh

---

## Development Workflow

### Commands

```bash
bun install           # Install dependencies
bun run dev           # Dev server (localhost:5173)
bun run build         # Build to dist/
bun run typecheck     # TypeScript validation (tsc --noEmit)
bun run preview       # Preview production build
```

### Deployment Process

**Production:** Cloudflare Pages (auto-deploys from `main` branch)  
**Live URL:** <https://seedpgp-web.pages.dev>

### Cloudflare Pages Setup

1. **Repository:** `seedpgp-web` (private repo)
2. **Build command:** `bun run build`
3. **Output directory:** `dist/`
4. **Security headers:** Automatically enforced via `public/_headers`

### Git Workflow

```bash
# Commit feature
git add src/
git commit -m "feat(v1.x): description"

# Push to main branch (including tags) triggers auto-deploy to Cloudflare
git tag v1.x.x
git push origin main --tags

# **IMPORTANT: Update README.md before tagging**
# Update the following sections in README.md:
# - Current version number in header
# - Recent Changes section with new features
# - Any new usage instructions or screenshots
# Then commit the README update:
git add README.md
git commit -m "docs: update README for v1.x.x"
```

---

## Required Workflow for AI Agents

### 1. Study First

Before implementing any feature:

- Read relevant files
- Explain current architecture + entry points
- List files that will be touched
- Identify potential conflicts or dependencies

### 2. Plan

- Propose smallest vertical slice (1-5 files)
- Show API signatures or interface changes first
- Get approval before generating full implementation

### 3. Implement

- Generate code with TypeScript strict mode
- Include JSDoc comments for public APIs
- Show unified diffs, not full file rewrites (when possible)
- Keep changes under 50-100 lines per file when feasible

### 4. Verify

- Run `bun run typecheck` - no errors
- Run `bun run build` - successful dist/ output
- Provide manual test steps for browser verification
- Show build output / console logs / DevTools screenshots

---

## Common Patterns

### State Management

- React `useState` + `useEffect` (no Redux/Zustand/external store)
- Ephemeral state only; avoid persistent storage for secrets

### Styling

- Tailwind utility classes (configured in `tailwind.config.js`)
- Responsive design: mobile-first with `md:` breakpoints
- Dark theme primary: slate-900 background, blue-400 accents

### Icons

- `lucide-react` library
- Common: Shield, QrCode, Lock, Eye, AlertCircle

### Crypto Operations

- **PGP**: OpenPGP.js (`openpgp` package)
- **Session keys**: Web Crypto API (`crypto.subtle`)
- **Key generation**: `crypto.subtle.generateKey()` with `extractable: false`
- **Encryption**: AES-GCM with random 12-byte IV per operation

### Type Safety

- Strict TypeScript (`tsconfig.json`: `strict: true`)
- Check `src/lib/types.ts` for core interfaces
- Avoid `any`; use `unknown` + type guards when necessary

---

## Security Architecture

### Threat Model (Honest)

**What we protect against:**

- Accidental persistence to localStorage/sessionStorage
- Plaintext secrets lingering in React state after use
- Clipboard history exposure (with warnings)

**What we DON'T protect against (and must not claim to):**

- Active XSS or malicious browser extensions
- Memory dumps or browser crash reports
- JavaScript garbage collection timing (non-deterministic)

### Memory Handling

- **Session keys**: Non-exportable CryptoKey objects (Web Crypto API)
- **Plaintext clearing**: Set to empty string + drop references (but GC timing is non-deterministic)
- **No guarantees**: Cannot force immediate memory wiping in JavaScript

### Storage Policy

- **NEVER write to**: localStorage, sessionStorage, IndexedDB, cookies
- **Exception**: Non-sensitive UI state only (theme preferences, etc.) - NOT IMPLEMENTED YET
- **Verification**: StorageIndicator component monitors all storage APIs

---

## What NOT to Do

### Code Generation

- Don't generate full file rewrites unless necessary
- Don't add dependencies without discussing bundle size impact
- Don't use `any` types without explicit justification
- Don't skip TypeScript strict mode checks

### Security Claims

- Don't claim "RAM is wiped" (JavaScript can't force GC)
- Don't promise protection against active browser compromise (XSS/extensions)

### Storage

- Don't write secrets to storage without explicit approval
- Don't cache decrypted data beyond immediate use
- Don't assume browser storage is secure

---

## Testing & Verification

### Manual Test Checklist (Before Marking Feature Complete)

1. ✅ `bun run typecheck` passes (no TypeScript errors)
2. ✅ `bun run build` succeeds (dist/ generated)
3. ✅ Browser test: Feature works as described
4. ✅ DevTools Console: No runtime errors
5. ✅ DevTools Application tab: No plaintext secrets in storage
6. ✅ DevTools Network tab: No unexpected network calls (if Read-only Mode)

### Session-Key Encryption Test (v1.3+)

```javascript
// In browser DevTools console:
await window.runSessionCryptoTest()
// Expected: ✅ Success: Data integrity verified.
```

---

## Current Version: v1.4.7

**Recent Changes (v1.4.5):**
- Fixed QR Scanner bugs related to camera initialization and race conditions.
- Improved error handling in the scanner to prevent crashes and provide better feedback.
- Stabilized component props to prevent unnecessary re-renders and fix `AbortError`.

**Known Limitations (Critical):**
1. **Browser extensions** can read DOM, memory, keystrokes - use dedicated browser
2. **Memory persistence** - JavaScript cannot force immediate memory wiping
3. **XSS attacks** if hosting server is compromised - host locally
4. **Hardware keyloggers** - physical device compromise not protected against
5. **Supply chain attacks** - compromised dependencies possible
6. **Quantum computers** - future threat to current cryptography

**Next Priorities:**
1. Enhanced BIP39 validation (full wordlist + checksum)
2. Multi-frame support for larger payloads
3. Hardware wallet integration (Trezor/Keystone)

---

## Quick Reference

### File a Bug/Feature

1. Describe expected vs actual behavior
2. Include browser console errors (if any)
3. Specify which flow (Backup/Restore/QR Scanner)

### Roll Over to Next Session

Always provide:

- Current version number
- What was implemented this session
- Files modified
- What still needs work
- Any gotchas or edge cases discovered

---

## Example Prompts for Gemini

### Exploration

```
Read GEMINI.md, then explain:
1. Where is the mnemonic textarea and how is its value managed?
2. List all places localStorage/sessionStorage are used
3. Show data flow from "Backup" button to QR display
```

### Feature Request

```
Task: [Feature description]

Requirements:
1. [Specific requirement]
2. [Another requirement]

Files to touch:
- [List files]

Plan first: show proposed API/changes before generating code.
```

### Verification

```
Audit the codebase to verify [feature] is fully implemented.
Check:
1. [Requirement 1]
2. [Requirement 2]
Output: ✅ or ❌ for each item + suggest fixes for failures.
```

---

**Last Updated**: 2026-01-29  
**Maintained by**: @kccleoc  
**AI Agent**: Optimized for Gemini Code Assist
