Grand Diomande Research · Full HTML Reader

cc-handguard: Shared Latent Stream Architecture

**Issues**: - ❌ Double battery drain on watch - ❌ Two separate upload streams - ❌ Two device IDs in backend - ❌ Two latent computations for same physical motion - ❌ Wasteful and redundant

Embodied Trajectory Systems architecture technical paper candidate score 50 .md

Full Public Reader

cc-handguard: Shared Latent Stream Architecture

Date: 2025-12-15
Status: 🎯 RECOMMENDED APPROACH

---

The Problem: Redundant Sensor Streams

Current Implementation

Apple Watch (100Hz sensors)
    ↓
    ├─→ EchelonCapture → Upload → CC-MCS device_1 → Latent stream 1
    └─→ HandGuard → Upload → CC-MCS device_2 → Latent stream 2

Issues:
- ❌ Double battery drain on watch
- ❌ Two separate upload streams
- ❌ Two device IDs in backend
- ❌ Two latent computations for same physical motion
- ❌ Wasteful and redundant

---

The Solution: Single Upload, Multiple Policies

Shared Latent Architecture

┌────────────────────────────────────────────────────────────┐
│                      Apple Watch                           │
│              Single 100Hz sensor stream                    │
└───────────────────────────┬────────────────────────────────┘
                            │
                            ↓
┌────────────────────────────────────────────────────────────┐
│                    iPhone Gateway                          │
│         (EchelonCapture OR HandGuard OR Shared)            │
│                                                            │
│  Option A: EchelonCapture handles upload                   │
│  Option B: HandGuard handles upload                        │
│  Option C: Shared "Sensor Gateway" app                     │
└───────────────────────────┬────────────────────────────────┘
                            │ Single upload stream
                            ↓
┌────────────────────────────────────────────────────────────┐
│              CC-MCS-Headless (Cloud Backend)               │
│                                                            │
│  Input: Single device_id stream                            │
│  Process: LIM-RPS solver → z(t) latent state               │
│  Output: Broadcast z(t) to ALL WebSocket subscribers       │
└───────────────────────────┬────────────────────────────────┘
                            │
                ┌───────────┴───────────┐
                ↓                       ↓
    ┌────────────────────┐   ┌────────────────────┐
    │  EchelonCapture    │   │    HandGuard       │
    │  (Policy Client)   │   │  (Policy Client)   │
    │                    │   │                    │
    │  Receives z(t)     │   │  Receives z(t)     │
    │  Applies Echelon   │   │  Applies nail-     │
    │  policy            │   │  biting policy     │
    │  Controls music    │   │  Fires haptics     │
    └────────────────────┘   └────────────────────┘

Benefits:
- ✅ Single sensor stream (50
- ✅ Single upload stream (50
- ✅ One device_id in backend
- ✅ Same z(t) latent state for all policies
- ✅ True "latent-first" philosophy
- ✅ Can run multiple policy apps simultaneously

---

Implementation Options

Option A: EchelonCapture as Gateway (Easiest)

Concept: EchelonCapture already uploads sensors. Add a local broadcast so HandGuard can subscribe.

Apple Watch
    ↓ (WatchConnectivity)
iPhone: EchelonCapture
    ├─→ Upload to CC-MCS (existing code)
    └─→ Local broadcast on [ip]:9001 (NEW)
           ↓
iPhone: HandGuard
    ├─→ Subscribe to local latent stream ws://[ip]:9001
    └─→ Apply nail-biting policy
    └─→ Send interventions to watch

Changes Required:

EchelonCapture (minimal):
1. Add local WebSocket server on port 9001
2. Broadcast latent states locally
3. ~50 lines of code

HandGuard:
1. Change `CCLatentSubscriber` to connect to `ws://[ip]:9001` instead of cloud
2. Remove `CCBridgeManager` (no upload needed)
3. Keep `HandGuardPolicy` and intervention logic
4. ~30 lines changed

Pros:
- ✅ Minimal changes
- ✅ EchelonCapture proven stable
- ✅ HandGuard becomes lightweight policy-only app

Cons:
- ❌ Requires EchelonCapture to be running
- ❌ HandGuard can't work standalone

---

Option B: HandGuard as Gateway (Current)

Concept: HandGuard uploads sensors (as currently built). EchelonCapture subscribes to same device_id.

Apple Watch
    ↓ (WatchConnectivity)
iPhone: HandGuard
    ├─→ Upload to CC-MCS (current code)
    └─→ Subscribe to cloud latent stream
    └─→ Apply nail-biting policy

iPhone: EchelonCapture (MODIFIED)
    └─→ Subscribe to same device_id latent stream
    └─→ Apply Echelon policy
    └─→ Control music

Changes Required:

HandGuard: No changes (current implementation)

EchelonCapture:
1. Remove sensor upload code
2. Subscribe to HandGuard's device_id WebSocket stream
3. ~50 lines changed

Pros:
- ✅ Current HandGuard code works as-is
- ✅ HandGuard works standalone

Cons:
- ❌ Requires modifying EchelonCapture
- ❌ EchelonCapture becomes dependent on HandGuard

---

Option C: Shared Sensor Gateway App (Best Long-Term)

Concept: Create a lightweight "CC Sensor Gateway" app that ONLY handles upload. Both EchelonCapture and HandGuard become pure policy clients.

Apple Watch
    ↓ (WatchConnectivity)
iPhone: CC Sensor Gateway (NEW APP)
    └─→ Upload to CC-MCS only
    └─→ No policy logic
    └─→ Minimal UI (connection status)

        CC-MCS broadcasts z(t)
               ↓
    ┌──────────┴──────────┐
    ↓                     ↓
iPhone: EchelonCapture   iPhone: HandGuard
(Policy only)            (Policy only)

Changes Required:

New App: CC Sensor Gateway (~500 lines)
1. WatchConnectivityManager
2. CCBridgeManager (upload only)
3. Simple status UI

EchelonCapture:
1. Remove upload code
2. Pure policy client

HandGuard:
1. Remove CCBridgeManager
2. Pure policy client

Pros:
- ✅ Clean separation of concerns
- ✅ Both policy apps lightweight
- ✅ Easy to add new policy apps
- ✅ Gateway can run in background

Cons:
- ❌ Requires building new app
- ❌ More initial work

---

Recommended Approach

Phase 1: Current (Keep As-Is for Now) ✅

Status: What we've built

  • HandGuard works standalone
  • Upload + policy in same app
  • Can test and validate immediately
  • Deploy this first, get it working

Phase 2: Shared Device ID (Quick Win)

After HandGuard is deployed and working:

1. Deploy HandGuard with fixed device_id:

swift
// In CCBridgeManager.swift
let deviceID = "watch-primary" // Hardcoded

2. Modify EchelonCapture to subscribe to same device_id:

swift
// In EchelonCapture latent subscriber
let wsURL = "wss://cc-mcs-headless.../latent?device_id=watch-primary"

3. Result: Both apps receive same latent state, different policies
- EchelonCapture still uploads (redundant but harmless)
- Both subscribe to same stream
- ~10 minute change

Phase 3: Gateway App (Future)

After validating shared latent works:

1. Build CC Sensor Gateway app
2. Migrate both apps to pure policy clients
3. Proper architecture

---

Implementation: Phase 2 (Recommended Next)

Let me modify the current HandGuard code to use a shared device_id:

Change 1: Fixed Device ID

File: `cc-handguard/Services/CloudBridge/CCBridgeManager.swift`

swift
// Line ~30
private let deviceID = "watch-primary" // Changed from UUID

// Remove this:
// private let deviceID = UUID().uuidString

Change 2: Document Device ID

File: `cc-handguard/Services/CloudBridge/CCLatentSubscriber.swift`

swift
// Line ~25
private let deviceID = "watch-primary" // Must match CCBridgeManager

init() {
    // Connect to shared device stream
    let urlString = "\(baseURL)/latent?device_id=\(deviceID)"
    // ...
}

Change 3: Update EchelonCapture

In EchelonCapture codebase (separate change):

python
# In latent_subscriber.py or equivalent
DEVICE_ID = "watch-primary"  # Match HandGuard
ws_url = f"wss://cc-mcs-headless.../latent?device_id={DEVICE_ID}"

Result

Apple Watch → HandGuard uploads as "watch-primary"
                    ↓
            CC-MCS processes stream
                    ↓
        Broadcasts z(t) for "watch-primary"
                    ↓
        ┌───────────┴───────────┐
        ↓                       ↓
    HandGuard               EchelonCapture
    (subscribed to          (subscribed to
    watch-primary)          watch-primary)

Both receive same z(t), apply different policies.

---

Code Changes for Shared Device ID

Want me to implement Phase 2 now? I can:

1. ✅ Update CCBridgeManager with fixed device_id
2. ✅ Update CCLatentSubscriber with same device_id
3. ✅ Add configuration file for device_id
4. ✅ Document how to configure EchelonCapture to use same device_id

This is a 10-minute change that eliminates the redundancy concern while keeping HandGuard functional.

---

Summary

Current: HandGuard uploads + subscribes (works standalone) ✅

Phase 2 (Recommended): Shared device_id
- HandGuard uploads as "watch-primary"
- EchelonCapture subscribes to "watch-primary"
- Both receive same z(t)
- 10-minute change

Phase 3 (Future): Gateway app
- Separate upload from policy
- Clean architecture
- Easy to add new apps

---

Decision Point

Question: Do you want to:

A) Keep current architecture (deploy HandGuard standalone) - READY NOW

B) Switch to shared device_id (10-minute change) - ELIMINATES REDUNDANCY

C) Build gateway app first (1-2 hours) - BEST LONG-TERM

I recommend A first (deploy and test), then B after verification.

What do you prefer?

Promotion Decision

Promote into a technical note or architecture paper with implementation anchors.

Source Anchor

Comp-Core/apps/ios/cc-handguard/SHARED_LATENT_ARCHITECTURE.md

Detected Structure

Method · Evaluation · Figures · Code Anchors · Architecture