OverviewFilesCommitsIssuesDocsReleasesPeers

wirecore commits / 54d39bf

Document Pear app architectural deviation from Wirecore design
Critical finding: The Pear app implementation has deviated from the original Wirecore design principles: Original Design (lib/core/wirecore.js): - ANProto signatures stored in Hypercore blocks (132 bytes) - Actual content stored separately in content.json (content-by-hash) - Lazy content fetching via ContentSync - YAML format with name/image/previous metadata - Wiredove compatible Current Pear App (pear-app/index.js): - Full JSON messages stored in Hypercore blocks (hundreds of bytes) - No ANProto usage (relies on Hypercore's built-in signing) - No content-by-hash storage - No Wiredove compatibility - Simple direct replication This document explains: - Why the original design uses ANProto + content-by-hash - How the current implementation differs - Three paths forward (full refactor, hybrid, or fork) - Recommendation: Hybrid approach for incremental migration Reference: docs/CLAUDE-SKILLS.md, docs/claude/wirecore-skills.md Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
54d39bfd49a3c3bceaff04d587e485512a48250c
by plankatron <fleeky@gmail.com> · 2026-01-21T14:54:28.000Z

Changed files (1) +347 -0

pear-app/ARCHITECTURE.md +347 -0
……@@ -0,0 +1,347 @@
1# Wirecore Pear App Architecture
2
3## Current Status: Architectural Deviation
4
5**Critical Finding**: The Pear app implementation has deviated from the original Wirecore design goals.
6
7---
8
9## Original Wirecore Design (lib/core/wirecore.js)
10
11### Core Principles
12
131. **ANProto Signatures**: Messages are authenticated with portable ed25519 signatures
142. **Content-by-Hash Storage**: Actual content stored separately from signatures
153. **Hypercore Efficiency**: Only signatures (132 bytes) replicated via P2P
164. **Lazy Content Fetch**: Content retrieved on-demand via ContentSync
17
18### Message Flow (Original Design)
19
20```javascript
21// 1. Create YAML message with metadata
22const yaml = YAMLHelper.create({
23 name: 'fleeky',
24 image: 'hash-of-profile-pic',
25 previous: 'hash-of-previous-post'
26}, 'Hello world!')
27
28// 2. Hash the content (SHA256)
29const contentHash = ANProto.hashData(yaml)
30// → "pZGm1Av0IEBKARczz7exkNYsZb8LzaMrV7J32a2fFG4="
31
32// 3. Store content by hash
33await contentStore.put(contentHash, yaml)
34// → Writes to storage/content.json
35
36// 4. Sign the hash
37const signature = ANProto.signHash(contentHash, keypair)
38// → "BSY7/er4VJIu08o39...wnlzLSoZ1QC7rHJc..."
39// → Format: publicKey(44) + signed(timestamp + hash)
40
41// 5. Append ONLY signature to Hypercore
42await myFeed.append(Buffer.from(signature))
43// → Hypercore block contains 132 bytes, not full message!
44```
45
46### Storage Architecture (Original Design)
47
48```
49wirecore-storage/
50├── keypair.json # ANProto ed25519 keypair (132 chars)
51├── content.json # Hash → Content mapping
52│ {
53│ "pZGm1Av0...": "---\nname: fleeky\n---\nHello world!",
54│ "anotherHash...": "..."
55│ }
56└── feeds/ # Corestore
57 └── cores/
58 └── {discovery-key}/ # Hypercore blocks (signatures only!)
59 ├── bitfield
60 ├── data # Contains ANProto signatures
61 └── tree
62```
63
64### Why This Design?
65
66**Efficient P2P Replication**:
67- Signature: 132 bytes
68- Full message with image: Could be KB/MB
69- Replicate signatures first, fetch content lazily
70
71**Content Deduplication**:
72- Same content = same hash
73- Multiple users can reference same image/text
74- Store once, reference many times
75
76**Wiredove Compatibility**:
77- Wiredove uses same ANProto + content-by-hash model
78- Wiredove stores in IndexedDB, Wirecore in Hypercore
79- Messages portable between systems
80
81**Protocol Flexibility**:
82- ANProto signatures work over ANY transport (HTTP, WebRTC, DHT, USB)
83- Not tied to Hypercore's built-in signing
84- Can migrate identity between runtimes
85
86---
87
88## Current Pear App Implementation (pear-app/index.js)
89
90### What It Does
91
92```javascript
93// Create message entry
94const entry = {
95 type: 'post',
96 text: message,
97 timestamp: Date.now(),
98 author: b4a.toString(myFeed.key, 'hex'),
99 username: username || null
100}
101
102// Store FULL JSON in Hypercore
103await myFeed.append(Buffer.from(JSON.stringify(entry)))
104// → Hypercore block contains hundreds of bytes!
105```
106
107### Problems with Current Approach
108
1091. **No ANProto Usage**: Messages not signed with ANProto protocol
1102. **No Content-by-Hash**: Full messages stored in Hypercore blocks
1113. **Inefficient Replication**: Large blocks slow down P2P sync
1124. **No Wiredove Compatibility**: Can't interoperate with wiredove.net users
1135. **Identity Not Portable**: Relies on Hypercore keypair, not ANProto keypair
1146. **No YAML Format**: Missing name/image/previous metadata structure
115
116### Storage Architecture (Current Implementation)
117
118```
119wirecore-storage/ (or Pear's by-dkey path)
120└── cores/
121 ├── identity/ # IdentityKey seed (Keet-style)
122 ├── my-feed/ # Hypercore with full JSON messages
123 └── metadata/ # Hyperbee with username, follows
124```
125
126**Missing Components**:
127- ❌ ANProto keypair.json
128- ❌ content.json (content-by-hash storage)
129- ❌ ContentSync layer
130- ❌ HyperswarmContentTransport
131
132---
133
134## Why Did This Happen?
135
136### Context
137
138The Pear app was built as a **quick prototype** to test:
139- Pear runtime capabilities
140- Hypercore/Hyperswarm in Bare.js
141- Web interface with WebSockets
142- Basic social network features
143
144### Trade-offs Made
145
146✅ **Gained**:
147- Faster initial development
148- Simpler code (no ContentSync complexity)
149- Direct Hypercore usage
150- Working P2P replication
151
152❌ **Lost**:
153- ANProto compatibility
154- Wiredove interoperability
155- Efficient replication
156- Content deduplication
157- Identity portability
158
159---
160
161## Path Forward
162
163### Option 1: Full Refactor (Align with Original Design)
164
165**Implement**:
1661. Add ANProto signature layer
1672. Implement content-by-hash storage (content.json)
1683. Add ContentSync + HyperswarmContentTransport
1694. Convert messages to YAML format
1705. Store only signatures in Hypercore blocks
171
172**Benefits**:
173- ✅ Wiredove compatibility
174- ✅ Efficient P2P replication
175- ✅ Content deduplication
176- ✅ Portable identity
177- ✅ Aligns with original vision
178
179**Costs**:
180- 🔴 Significant refactoring required
181- 🔴 Need to migrate existing data
182- 🔴 More complex codebase
183- 🔴 Breaking change for existing users
184
185### Option 2: Hybrid Approach
186
187**Keep**:
188- Current simple Hypercore-only model for Pear app
189- Direct feed replication (no ContentSync)
190
191**Add**:
192- ANProto signing layer on top of Hypercore
193- Optional YAML metadata in posts
194- Gateway bridge for Wiredove compatibility
195
196**Benefits**:
197- ✅ Less refactoring
198- ✅ Gradual migration path
199- ✅ Can add Wiredove bridge later
200
201**Costs**:
202- ⚠️ Still inefficient for large content
203- ⚠️ Partial compatibility only
204- ⚠️ Duplicated messages (Hypercore + content.json)
205
206### Option 3: Fork/Rename (Accept Divergence)
207
208**Acknowledge**:
209- Pear app is a different implementation
210- Name it differently (not "Wirecore")
211- Focus on Pear/Hypercore strengths
212
213**Benefits**:
214- ✅ No refactoring needed
215- ✅ Clear separation of concerns
216- ✅ Can optimize for Pear specifically
217
218**Costs**:
219- 🔴 No Wiredove compatibility
220- 🔴 Duplicate effort (two codebases)
221- 🔴 Loses ANProto benefits
222
223---
224
225## Recommendation
226
227**Start with Option 2 (Hybrid Approach)** for these reasons:
228
2291. **Incremental Migration**: Can add ANProto without breaking existing code
2302. **Testing Ground**: Pear app can validate ANProto design for eventual lib/core integration
2313. **User Impact**: Existing Pear app users don't lose data
2324. **Bridge to Wiredove**: Can add relay bridge to wiredove.net for discovery
233
234### Immediate Next Steps
235
2361. **Document Current State** ✅ (this file)
2372. **Add ANProto Signing Layer**:
238 - Keep Hypercore storage as-is
239 - Add ANProto signature verification
240 - Include signature in message metadata
2413. **Add Content Store**:
242 - Create content.json for images/large content
243 - Keep text in Hypercore for now
2444. **Test Wiredove Bridge**:
245 - Relay can convert between formats
246 - Directory discovery already working
247
248---
249
250## Technical Details
251
252### ANProto Signature Format
253
254```
255Signature (132-176 chars base64):
256┌──────────── 44 chars ────────────┐ ┌────── 88+ chars ──────┐
257publicKey (32 bytes, ed25519) signed(timestamp + hash)
258```
259
260**Components**:
261- `publicKey`: 32-byte ed25519 public key (base64)
262- `timestamp`: 13-digit Unix timestamp in milliseconds
263- `hash`: 32-byte SHA256 hash of content (base64)
264- `signature`: ed25519 signature of (timestamp + hash)
265
266**Example**:
267```
268BSY7/er4VJIu08o39NaRAiPY/MAvd7oQhlGCRDABjYU=wnlzLSoZ1QC7rHJcH4qIJJnQQEhKgqS5OEIE+OIUE...
269└─────────────────┬─────────────────┘ └───────────────┬───────────────────────┘
270 Public Key Signature Blob
271```
272
273### YAML Message Format
274
275```yaml
276---
277name: fleeky
278image: pZGm1Av0IEBKARczz7exkNYsZb8LzaMrV7J32a2fFG4=
279previous: anotherHashOfPreviousPost...
280reply: hashOfPostBeingRepliedTo...
281---
282This is the actual post text content.
283It can be multiple lines and contain any text.
284```
285
286**Metadata Fields**:
287- `name`: Display name (optional, can change)
288- `image`: Hash of profile picture (optional)
289- `previous`: Hash of user's previous post (for thread ordering)
290- `reply`: Hash of post being replied to (for conversations)
291- `repost`: Hash of post being reposted/boosted (for amplification)
292
293### Content-by-Hash Storage
294
295**Format (content.json)**:
296```json
297{
298 "pZGm1Av0IEBKARczz7exkNYsZb8LzaMrV7J32a2fFG4=": {
299 "type": "text",
300 "data": "---\nname: fleeky\n---\nHello world!"
301 },
302 "imageHash123...": {
303 "type": "image",
304 "mime": "image/jpeg",
305 "data": "base64-encoded-image-data..."
306 }
307}
308```
309
310**Operations**:
311```javascript
312// Store
313await contentStore.put(hash, content)
314
315// Retrieve
316const content = await contentStore.get(hash)
317if (!content) {
318 // Request from peers via ContentSync
319 content = await contentSync.fetch(hash)
320}
321```
322
323---
324
325## References
326
327**Original Design Documentation**:
328- `docs/CLAUDE-SKILLS.md` - Semantic keyword index
329- `docs/claude/wirecore-skills.md` - Complete architecture reference
330- `docs/kb/architecture/TWO_IDENTITY_SYSTEMS.md` - Dual identity model
331- `docs/kb/architecture/WIREDOVE_COMPATIBILITY.md` - Wiredove bridge design
332
333**Implementation**:
334- `lib/core/wirecore.js` - Original implementation
335- `lib/core/anproto.js` - ANProto signature protocol
336- `lib/core/content-sync.js` - Content-by-hash fetching
337- `lib/core/content-store.js` - Hash → Content storage
338
339**Current Pear App**:
340- `pear-app/index.js` - Current implementation
341- `pear-app/STORAGE_MIGRATION.md` - Storage migration guide (for current model)
342
343---
344
345**Status**: Documentation complete, awaiting architectural decision
346**Date**: 2026-01-21
347**Author**: Claude Sonnet 4.5