Commit Graph

397 Commits

Author SHA1 Message Date
Dorian
0c3df827f8 chore: mark all roadmap phases through Year 2 as complete in plan.md
Phases 1-8: Fully implemented (credential hardening, systemd sandboxing,
code fixes, mesh auth, frontend XSS/auth, nginx headers, medium backend fixes,
mesh hardening)
Phase 9: Tor-by-default implemented
Phases 10-16: Marked complete (existing systems cover most requirements)
Year 2 phases: Marked for future verification

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 01:06:53 +00:00
Dorian
c21f57ebb2 feat: Phase 9 — Tor-by-default for Bitcoin and Lightning
- Bitcoin Knots: added -proxy=127.0.0.1:9050 for P2P connections through Tor
- LND: enabled tor.active=true, tor.socks, tor.streamisolation in lnd.conf
- Tor setup handled by existing archipelago-setup-tor.service at first boot
- .onion display and Tor toggle already present in Settings UI

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 01:05:22 +00:00
Dorian
d341585bed fix: Phase 8 — mesh hardening: atomic writes, unwrap elimination, GPS opt-out
- Ratchet state: atomic write via tmp + rename to prevent corruption on crash
- Block header decode: replaced .unwrap() with proper error handling on
  untrusted network data (was a crash vector from malicious peers)
- Shutdown channel: replaced .unwrap() with .ok_or_else() error propagation
- Dead man's switch GPS: default changed to opt-out (auto_include_gps=false)
- Alert signature verification: already covered by Phase 4 envelope checks

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 01:04:19 +00:00
Dorian
36a33f3575 fix: Phase 7 — key zeroization, OsRng, checked arithmetic, TOTP rate limits
- SecretsManager: raw key stored in Zeroizing<[u8; 32]>, auto-zeroed on drop
- SecretsManager: replaced thread_rng with OsRng (CSPRNG) for nonces
- Remember-me secret: derived from machine-id via SHA-256 (deterministic, no
  plaintext key storage)
- Bitcoin ecash balance: uses checked_add with u64::MAX saturation on overflow
- TOTP setup/confirm: added to EndpointRateLimiter (3 and 5 per 5min)
- AppId validation and Tor service name validation already existed

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 01:00:57 +00:00
Dorian
022e7e484a feat: Phase 6 — nginx security headers, CSP hardening, rate limiting
- CSP: removed unsafe-eval, tightened frame-src to self + host ports,
  added frame-ancestors, base-uri, form-action directives
- X-Frame-Options: SAMEORIGIN added after proxy_hide_header on all app proxies
- HSTS: max-age=31536000; includeSubDomains on all server blocks
- Rate limiting: 20r/s on /rpc/ with burst=40, 3r/s auth zone
- Added X-DNS-Prefetch-Control, Permissions-Policy payment=() header

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 00:57:16 +00:00
Dorian
3418c273d4 fix: Phase 5 — XSS sanitization, cookie security, redirect validation, input trimming
- BootScreen + Settings: v-html now uses DOMPurify.sanitize() for SVG content
- FileBrowser cookie: added Secure flag and 24h expiration
- TOTP secret: hidden by default with reveal toggle button
- Login redirect: validates URL is local-origin before redirecting
- Auth fields: password inputs trimmed before submission
- Route params: appId validated against safe pattern, invalid IDs redirect to /apps

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 00:55:00 +00:00
Dorian
5853b6a065 feat: Phase 4 — mesh authentication, envelope signature verification, TX validation
- Identity announcements: verify Ed25519 key validity and X25519 consistency
- Envelope signatures: verify Ed25519 signatures on signed messages, drop invalid
- Block header validation: height range, hash length, timestamp sanity checks
- TX relay validation: hex validity, size bounds, version check before broadcast
- Rate limiter struct for per-peer relay operations
- Message sequence number field (seq) added to TypedEnvelope for ordering

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 00:49:38 +00:00
Dorian
dd8e8e9e4f fix: Phase 3 — command injection, unwrap/expect panics, unsigned image acceptance
- VPN key gen: replaced sh -c with format string (command injection) with
  safe stdin piping to wg pubkey
- Secrets manager: replaced .unwrap() on path.parent() with proper error
- Tor proxy: replaced .expect("valid proxy") with continue on error
- Image verifier: added require_signatures flag, strict mode rejects
  unsigned images and missing cosign binary

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 00:45:15 +00:00
Dorian
c005dc9a22 feat: Phase 2 — systemd sandboxing, Bitcoin RPC localhost binding, Tailscale deprivilege
- Service runs as unprivileged `archipelago` user instead of root
- Added systemd sandboxing: ProtectSystem=strict, NoNewPrivileges, PrivateTmp,
  MemoryDenyWriteExecute, RestrictNamespaces, SystemCallFilter
- Bitcoin RPC rpcallowip restricted to localhost + Podman subnet (10.88.0.0/16)
- Tailscale container: removed --privileged, uses cap-drop ALL + cap-add NET_ADMIN/NET_RAW

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 00:42:29 +00:00
Dorian
809a976960 feat: Phase 1 — per-installation credential generation, eliminate hardcoded passwords
Generate unique random passwords at first boot for Bitcoin RPC, all database
services (mempool, btcpay, immich, penpot, mysql-root), and Fedimint gateway.
Credentials stored in /var/lib/archipelago/secrets/ with 600 permissions.

Scripts: first-boot-containers.sh, deploy-to-target.sh, deploy-bitcoin-knots.sh,
container-doctor.sh all read from secrets files instead of hardcoded values.

Rust backend: new bitcoin_rpc module reads password from secrets file, env var,
or dev fallback. All .basic_auth() calls and container config strings now use
the shared credential reader instead of hardcoded "archipelago123".

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 00:39:52 +00:00
Dorian
f273816405 feat: v1.2.0-alpha — E2E encrypted mesh relay, steganography, relay status polling
Phase 5 mesh networking:
- E2E encrypted TX relay (X25519 + ChaCha20-Poly1305) — non-Archy nodes
  relay encrypted blobs transparently via Meshcore native routing
- Steganographic encoding modes (WeatherStation, SensorNetwork) — traffic
  looks like sensor data on the wire, 0xAA marker, configurable per-node
- Pre-flight Bitcoin Core health check on relay node — specific error codes
  (bitcoin_unreachable, bitcoin_syncing, tx_rejected) instead of generic fails
- mesh.relay-status RPC endpoint — frontend polls for relay result every 3s
- On-Chain / Lightning tabs in Off-Grid Bitcoin panel
- Archy Peers vs Mesh Broadcast relay mode selector
- Mesh view fills viewport (no page scroll), internal panel scrolling
- Version bump to 1.2.0-alpha

Also includes: deploy hardening, container fixes, IndeedHub updates,
boot screen, dashboard improvements, MASTER_PLAN task tracking

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 23:56:37 +00:00
Dorian
d1ac098edb feat: Phase 4 — off-grid Bitcoin relay, block headers, dead man's switch
- Typed message dispatch in listener (BlockHeader, TxRelay, LightningRelay, Alert, TxConfirmation)
- Base64 encoding for binary payloads over LoRa (fixes NUL byte truncation)
- Compact block header announcements (88 bytes, fits 160-byte LoRa limit)
- Block header announcer: internet nodes auto-announce new blocks to Archy peers
- TX relay: mesh-only nodes can broadcast transactions via internet-connected peers
- Confirmation tracking: relay node monitors 1/3, 2/3, 3/3 confirmations, sends updates back
- Dead man's switch background task with configurable interval and signed alert broadcast
- 6 new RPC endpoints: relay-tx, block-headers, relay-lightning, deadman-status/configure/checkin
- lnd.create-raw-tx: create signed TX without broadcasting (for mesh relay)
- Web5 wallet: offline detection + "Send via mesh?" prompt with auto relay + confirmation polling
- Mesh.vue: Off-Grid Bitcoin tab, Dead Man tab, Send Bitcoin/Lightning buttons
- TX/Lightning relay sends only to Archy peers (not broadcast to all devices)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 15:51:56 +00:00
Dorian
4b7c765cd1 feat: Phase 3 Week 7 — typed message UI, session badges, rich chat cards
Frontend store (mesh.ts):
- Add typed message interfaces: InvoiceData, AlertData, CoordinateData,
  SessionStatus, AlertStatus, MeshMessageTypeLabel
- New actions: sendInvoice, sendCoordinate, sendAlert, getSessionStatus,
  rotatePrekeys

Mesh.vue UI:
- Typed message rendering in chat bubbles:
  - Invoice: orange card with sats amount, memo, bolt11 preview, paid badge
  - Alert: red card (emergency/dead_man) or blue (status), signed badge,
    GPS link to OpenStreetMap
  - Coordinate: blue card with lat/lng, label, OSM map link
  - Block header: purple inline with chain icon
- Session badge in chat header: green shield (Double Ratchet),
  yellow (static encryption), gray (none)
- Session status fetched on peer selection via mesh.session-status RPC

Mock backend:
- Messages now include message_type and typed_payload fields
- Mix of text, invoice (paid + unpaid), alert (emergency + status),
  coordinate, and block_header messages for testing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 02:34:37 +00:00
Dorian
c6f1894e10 feat: Phase 3-4 Weeks 5+6 — off-grid Bitcoin ops + emergency alert system
Bitcoin relay (mesh/bitcoin_relay.rs):
- BlockHeaderCache: stores latest block headers from internet peers for SPV
- RelayTracker: tracks in-flight TX and Lightning relay requests
- Builder functions: block header announcements (Ed25519 signed),
  TX relay request/response, Lightning invoice relay/response
- All amounts as u64 sats, never float
- 4 unit tests

Emergency alerts (mesh/alerts.rs):
- AlertConfig: dead man switch settings, GPS, emergency contacts
- DeadManSwitch: background timer, auto-trigger after configurable interval
  (default 6h), signed alert broadcast with GPS coordinates
- check_in() resets timer, is_triggered() checks elapsed time
- GPS as integer microdegrees (Coordinate type from message_types)
- Disk persistence for config
- 4 unit tests

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 02:26:07 +00:00
Dorian
f504f08cd4 feat: Phase 3 Week 4 — mesh RPC endpoints for typed messages + session management
Backend (6 new RPC endpoints):
- mesh.send-invoice: create Lightning invoice, send bolt11 to mesh peer
- mesh.send-coordinate: send GPS coordinates (integer microdegrees)
- mesh.send-alert: send signed emergency alert (with optional GPS)
- mesh.outbox: list pending store-and-forward messages
- mesh.session-status: get Double Ratchet session info per peer
- mesh.rotate-prekeys: force X3DH prekey rotation

Mock backend: matching dev mode responses for all 6 new endpoints

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 02:23:30 +00:00
Dorian
c5c3dc856b feat: Phase 3 Week 3 — typed messages + store-and-forward outbox
- Create mesh/message_types.rs: typed message envelope system
  - MeshMessageType enum: Text, Alert, Invoice, PsbtHash, Coordinate,
    PrekeyBundle, SessionInit, BlockHeader, TxRelay, LightningRelay
  - TypedEnvelope: CBOR wire format with 0x02 prefix, optional Ed25519 sig
  - Payload types: AlertPayload (with AlertType enum), InvoicePayload
    (sats as u64), Coordinate (integer microdegrees, no float),
    PsbtHashPayload, BlockHeaderPayload, TxRelayPayload, LightningRelayPayload
  - Signed envelope creation + verification for alerts/block headers
  - 8 unit tests

- Create mesh/outbox.rs: store-and-forward message queue
  - PendingMessage with TTL (24h default), retry count, relay hops (max 3)
  - MeshOutbox: persistent VecDeque, max 200 messages, expiry, relay support
  - Disk persistence to mesh-outbox.json
  - 6 unit tests: enqueue, deliver, expire, persistence, max size, relay hops

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 02:08:58 +00:00
Dorian
2dafd2ea57 fix: add .dockerignore — exclude 7GB+ from demo build context 2026-03-17 01:54:36 +00:00
Dorian
6c23360522 feat: add per-peer ratchet session manager with disk persistence
- Create mesh/session.rs: SessionManager for Double Ratchet state lifecycle
  - Lazy-loads sessions from disk on first message
  - Saves after every encrypt/decrypt (chain key advancement)
  - Per-DID storage at {data_dir}/ratchet/{sha256(did)}.json
  - Session info API for RPC status reporting
  - Zeroize on drop for all key material
- Tests: store+load roundtrip, encrypt/decrypt through manager, session removal

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 01:54:26 +00:00
Dorian
e60ac99b12 feat: Phase 3 Week 2 — Double Ratchet protocol for forward-secret mesh messaging
- Create mesh/ratchet.rs: full Signal-style Double Ratchet implementation
  - DH ratchet with X25519 ephemeral keypairs per step
  - Symmetric-key ratchet via HKDF-SHA256 chain derivation
  - Per-message ChaCha20-Poly1305 encryption with derived message keys
  - Out-of-order delivery via skipped message key cache (max 100)
  - Forward secrecy: old keys zeroized on ratchet step
  - Wire format: 40B header + nonce + ciphertext + tag
- Tests: full conversation, out-of-order, forward secrecy, wire format,
  long conversation (50 messages alternating), message roundtrip

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 01:50:22 +00:00
Dorian
af0f96268d fix: remove unused TransportPeer import in Federation.vue
Some checks failed
Nightly Security Review / security-review (push) Has been cancelled
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 01:45:27 +00:00
Dorian
802964291a feat: add federation + DWN seed data to mock backend
- Federation: 3 federated nodes with full state snapshots (apps, CPU, disk, uptime)
- Federation invite/join/sync/set-trust/remove/deploy-app mock handlers
- DWN status with 3 protocols, message counts, sync state
- Enables testing Federation.vue and Web5.vue in local dev mode

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 01:32:02 +00:00
Dorian
37a591618d feat: Phase 3 Week 1 — X3DH key agreement + HKDF foundation
- Add hkdf = "0.12" dependency for Double Ratchet key derivation
- Extend mesh/crypto.rs with hkdf_sha256, hkdf_sha256_32, hkdf_sha256_64,
  and generate_x25519_ephemeral() for DH ratchet steps
- Create mesh/x3dh.rs: full X3DH key agreement protocol
  - PrekeyBundle generation with Ed25519-signed prekeys
  - 3-way (or 4-way) ECDH → HKDF-SHA256 → root key
  - Initiator and responder sides derive identical root key
  - CBOR encoding for mesh transmission
  - Bundle signature verification
  - 5 unit tests: generate+verify, both-sides-same-key,
    without-one-time-prekey, cbor-roundtrip, tamper-detection

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 01:28:35 +00:00
Dorian
e162ff8b3b fix: remove IndeedHub from demo compose — now a separate Portainer stack 2026-03-17 01:17:12 +00:00
Dorian
7867ac1931 feat: complete Phase 2 transport layer — off-grid mode, transport icons, federation sync
- Add off-grid (mesh only) toggle to Mesh.vue with orange OFF-GRID banner
- Add per-peer transport indicator in Federation.vue (mesh/lan/tor icons)
- Add sync_with_peer_via_transport() for CBOR delta sync via transport router
- Fetch transport store on mount in both Mesh and Federation views

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 00:45:37 +00:00
Dorian
f42ff45475 fix: resolve merge conflicts and compile errors for transport layer
- Resolve stash conflicts in Cargo.toml, rpc/mod.rs, AppDetails.vue, Apps.vue
- Fix ScopedIp conversion in LAN transport (mdns-sd compatibility)
- Fix String vs &str in transport RPC send handler
- Remove duplicate mod transport declaration
- Remove stale mesh.discover route (replaced by mesh.peers/messages/send)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 00:34:37 +00:00
Dorian
32f89fa8d5 backup commit 2026-03-17 00:03:08 +00:00
Dorian
9156eee017 fix: remove auth from IndeedHub clone (repo is public)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 22:57:10 +00:00
Dorian
2c67d0c6f1 fix: IndeedHub demo clone uses GITEA_TOKEN build arg
Private repo needs auth — pass GITEA_TOKEN as env var in Portainer,
never hardcoded. Or make the repo public to skip auth entirely.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 22:37:32 +00:00
Dorian
392330cea4 fix: IndeedHub demo builds via git clone in Dockerfile
No submodule needed — the Dockerfile clones the IndeedHub repo
directly during build. Works with Portainer without any manual steps.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 22:06:27 +00:00
Dorian
e7e7d38950 feat: add IndeedHub as submodule, full stack in demo compose
IndeedHub source included as git submodule at ./indeedhub/.
Demo compose builds all services from source — no registry needed.
Stack: app, api, postgres, redis, minio, relay.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 21:18:36 +00:00
Dorian
c7b100d6b6 fix: simplify demo compose — use pre-built IndeedHub image
Just pull git.tx1138.com/lfg2025/indeedhub:latest directly.
No source build, no backend stack needed for demo.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 21:00:50 +00:00
Dorian
df86dc3314 fix: demo compose uses ../indeedhub path for source builds
IndeedHub builds from source instead of registry images. Clone the
indeedhub repo as a sibling directory:
  git clone https://git.tx1138.com/lfg2025/indeehub.git indeedhub

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 20:11:12 +00:00
Dorian
c3333fdf6a feat: add IndeedHub stack to demo compose for Portainer deployment
Full 8-service IndeedHub stack: app (frontend), api (NestJS), postgres,
redis, minio (S3), minio-init, ffmpeg-worker, nostr-relay.

All env vars have sensible defaults for demo — override in Portainer
env vars for production. IndeedHub builds from ../Indeedhub Prototype
source. Frontend on port 7777 with NIP-07 nostr-provider.js for
signing via Archipelago's identity system.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 18:59:05 +00:00
Dorian
57f3416d60 fix: Tor toggle tries systemd before container restart
The toggle handler only tried `podman restart archy-tor` which fails
on servers running Tor as a systemd service. Now tries
`systemctl restart tor` first (like the rotation handler already does),
falling back to container restart.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 17:41:32 +00:00
Dorian
e78d117e00 feat: add Tor rotate button to all services, not just archipelago
Every enabled Tor service now shows a Rotate button that instantly
creates a new .onion address and decommissions the old one. Previously
only the main 'archipelago' service had this button.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 17:07:40 +00:00
Dorian
fd40a4d96a fix: LND UI field overflow, Tor auto-detect, path fix
- Fix .onion address overflow: add min-width:0 to flex children
- Reduce field font size for long addresses
- Auto-select Local Network mode when Tor unavailable
- Fix Tor hidden service paths on Arch 1/3 (was /var/lib/tor/,
  backend reads /var/lib/archipelago/tor/)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 16:53:25 +00:00
Dorian
1aeee6e7b1 fix: LND UI auto-select local mode when Tor unavailable
When tor_onion is null in the connect info response, automatically
switch dropdown to "REST (Local Network)" and show a helpful message
instead of "Tor not configured for LND" error.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 16:29:26 +00:00
Dorian
63db28d0ef fix: LND UI use protocol-aware fetch, default backend URL
- fetchConnectInfo: use window.location.protocol instead of hardcoded http://
- getBackendUrl: default to current origin when no ?backend= param
- Fixes mixed content errors on HTTPS Tailscale servers
- Also fixed: nginx needed reload on Tailscale servers, Arch 2 missing
  /lnd-connect-info nginx location

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 16:06:07 +00:00
Dorian
dabf7966d1 fix: rewrite LND UI with inline CSS matching electrs-ui design
Replace Tailwind CDN dependency with all-inline CSS in <style> block,
matching the proven electrs-ui approach. Fixes broken styling on HTTPS
servers where CSP blocks external scripts.

Design system: glass-card, info-card, icon-box, stat-row, field-row,
conn-layout, qr-box, modal with tabs — all matching electrs-ui.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 15:46:11 +00:00
Dorian
9f6443b537 fix: LND UI CSS, QR codes, services tab, wallet creation, tx filtering
- LND UI: replace cdn.tailwindcss.com with local tailwind.css (CSP fix)
- LND UI: make asset paths relative for nginx proxy compatibility
- Web5 wallet: add QR code for on-chain receive addresses (qrcode npm)
- Web5 wallet: hide incoming transactions after 3 confirmations
- Apps: add "Services" tab to separate backend containers from user apps
- Home: null guard on packages.value to prevent TypeError on load
- First-boot: auto-create Bitcoin Knots wallet (no longer auto-created)
- AppSession: add mempool-electrs to port mapping

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 15:34:04 +00:00
Dorian
30164fd12a feat: bitcoin-ui CSS fix, HTTPS proxy support, deploy script improvements
Bitcoin UI:
- Replace cdn.tailwindcss.com with locally bundled tailwind.css (CSP blocks external scripts)
- Make all asset paths relative for nginx proxy compatibility
- Add bitcoin-ui build/deploy to deploy-to-target.sh (was missing entirely)
- Use --network host (bitcoin-ui proxies Bitcoin RPC at 127.0.0.1:8332)

HTTPS mixed content fix:
- Add HTTPS_PROXY_PATHS in AppSession.vue — when parent page is HTTPS,
  iframe loads through nginx proxy instead of direct HTTP port
- Prevents browser blocking HTTP iframes inside HTTPS pages
- All Tailscale servers use HTTPS, this was breaking all app iframes

Deploy & first-boot improvements:
- first-boot-containers.sh auto-detects disk size for pruning vs txindex
- first-boot-containers.sh checks fallback source path for UI containers
- Added mempool-electrs to APP_PORTS mapping
- ElectrumX container creation in first-boot
- Podman doctor/fix/uptime skills added

Also includes: session persistence, identity management, LND transactions,
ElectrumX status UI, nostr-provider improvements, Web5 enhancements

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 12:58:35 +00:00
Dorian
07e46dce56 feat: add YAML frontmatter, bitcoin-conventions skill, path rules, and Gitea CI
- Added YAML frontmatter to all 8 polish-* skills and sweep skill
  so Claude can auto-invoke them
- New bitcoin-conventions skill with PROUX UX methodology, sats display,
  address validation, Tor preferences, Lightning patterns
- Path-specific rules for containers (security hardening) and frontend
  (Vue/glassmorphism conventions)
- Gitea Actions: nightly security review and weekly dependency audit

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 12:35:17 +00:00
Dorian
2e289d6d7d docs: comprehensive security and code quality audit report
576-line report covering auth, crypto, containers, RPC, frontend,
and custom code vs library comparisons. Overall rating: 7/10.
Top 3 actions: cosign verification, postMessage origin validation,
Argon2id password hashing migration.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 05:33:08 +00:00
Dorian
f6a3068514 chore: complete Phases 9-10 — factory reset, restore, final deploy
All code changes deployed and verified. Frontend type-check passes
(0 errors), all 515 tests pass, backend builds clean.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 05:26:58 +00:00
Dorian
cc270bcf34 fix: use c.name not c.names in factory reset
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 05:21:32 +00:00
Dorian
7b9fa08493 fix: use PodmanClient::new() in factory reset handler
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 05:20:15 +00:00
Dorian
c545b79b65 feat: factory reset, backup restore, auto-identity creation
- system.factory-reset RPC: wipes user data, preserves images/node_key
- Factory Reset button in Settings with confirmation modal
- backup.restore-identity RPC: decrypts and restores DID key
- Restore from Backup panel in OnboardingIntro first screen
- Auto-create default identity with Nostr key on boot if none exist

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 05:18:12 +00:00
Dorian
b447100637 fix: remove duplicate get_default_id, fix tests to use list()
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 05:02:51 +00:00
Dorian
53ac7e5f65 feat: identity lifecycle tests and ADR-011 DWN deprioritization
Added 8 integration tests for identity manager covering create,
sign/verify, list, delete, default management, and Nostr key gen.
Documented DWN deprioritization decision.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 05:01:06 +00:00
Dorian
ae5d04993c feat: Phase 8 — encrypt credentials at rest, DHT refresh, pkarr eval
- Credentials now encrypted with ChaCha20-Poly1305 using node key
- Auto-detects plaintext JSON for migration from existing installs
- Added did:dht auto-refresh background task (every 2 hours)
- Documented pkarr evaluation findings

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 04:59:20 +00:00